<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <meta name="renderer" content="webkit">
  <meta http-equiv="X-UA-Compatible" content="IE=edge" >
  <link rel="dns-prefetch" href="http://black-and-astringent.gitee.io/blog">
  <title>Hexo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta property="og:type" content="website">
<meta property="og:title" content="Hexo">
<meta property="og:url" content="http://black-and-astringent.gitee.io/blog/page/2/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:locale" content="en_US">
<meta property="article:author" content="John Doe">
<meta name="twitter:card" content="summary">
  
    <link rel="alternative" href="/atom.xml" title="Hexo" type="application/atom+xml">
  
  
    <link rel="icon" href="https://s3.bmp.ovh/imgs/2022/02/71d00845ff7315ad.jpg">
  
  <link rel="stylesheet" type="text/css" href="/blog/./main.0cf68a.css">
  <style type="text/css">
  
    #container.show {
      background: linear-gradient(200deg,#a0cfe4,#e8c37e);
    }
  </style>
  

  

<meta name="generator" content="Hexo 6.0.0"></head>

<body>
  <div id="container" q-class="show:isCtnShow">
    <canvas id="anm-canvas" class="anm-canvas"></canvas>
    <div class="left-col" q-class="show:isShow">
      
<div class="overlay" style="background: #4d4d4d"></div>
<div class="intrude-less">
	<header id="header" class="inner">
		<a href="/blog" class="profilepic">
			<img src="https://s3.bmp.ovh/imgs/2022/05/20/2e44a68ec353884c.jpg" class="js-avatar">
		</a>
		<hgroup>
		  <h1 class="header-author"><a href="/blog"></a></h1>
		</hgroup>
		

		<nav class="header-menu">
			<ul>
			
				<li><a href="/blog/">主页</a></li>
	        
				<li><a target="_blank" rel="noopener" href="https://blog.csdn.net/qq_45188736?type=lately">CSDN</a></li>
	        
			</ul>
		</nav>
		<nav class="header-smart-menu">
    		
    			
    			<a q-on="click: openSlider(e, 'innerArchive')" href="javascript:void(0)">所有文章</a>
    			
            
    			
    			<a q-on="click: openSlider(e, 'friends')" href="javascript:void(0)">友链</a>
    			
            
    			
    			<a q-on="click: openSlider(e, 'aboutme')" href="javascript:void(0)">关于我</a>
    			
            
		</nav>
		<nav class="header-nav">
			<div class="social">
				
					<a class="github" target="_blank" href="#" title="github"><i class="icon-github"></i></a>
		        
					<a class="qq" target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin=2240073238&site=qq&menu=yes" title="qq"><i class="icon-qq"></i></a>
		        
					<a class="weixin" target="_blank" href="#" title="weixin"><i class="icon-weixin"></i></a>
		        
					<a class="bilibili" target="_blank" href="#" title="bilibili"><i class="icon-bilibili"></i></a>
		        
					<a class="mail" target="_blank" href="mailto:2240073238@qq.com" title="mail"><i class="icon-mail"></i></a>
		        
			</div>
		</nav>
	</header>		
</div>

    </div>
    <div class="mid-col" q-class="show:isShow,hide:isShow|isFalse">
      
<nav id="mobile-nav">
  	<div class="overlay js-overlay" style="background: #4d4d4d"></div>
	<div class="btnctn js-mobile-btnctn">
  		<div class="slider-trigger list" q-on="click: openSlider(e)"><i class="icon icon-sort"></i></div>
	</div>
	<div class="intrude-less">
		<header id="header" class="inner">
			<div class="profilepic">
				<img src="https://s3.bmp.ovh/imgs/2022/05/20/2e44a68ec353884c.jpg" class="js-avatar">
			</div>
			<hgroup>
			  <h1 class="header-author js-header-author"></h1>
			</hgroup>
			
			
			
				
			
				
			
			
			
			<nav class="header-nav">
				<div class="social">
					
						<a class="github" target="_blank" href="#" title="github"><i class="icon-github"></i></a>
			        
						<a class="qq" target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin=2240073238&site=qq&menu=yes" title="qq"><i class="icon-qq"></i></a>
			        
						<a class="weixin" target="_blank" href="#" title="weixin"><i class="icon-weixin"></i></a>
			        
						<a class="bilibili" target="_blank" href="#" title="bilibili"><i class="icon-bilibili"></i></a>
			        
						<a class="mail" target="_blank" href="mailto:2240073238@qq.com" title="mail"><i class="icon-mail"></i></a>
			        
				</div>
			</nav>

			<nav class="header-menu js-header-menu">
				<ul style="width: 50%">
				
				
					<li style="width: 50%"><a href="/blog/">主页</a></li>
		        
					<li style="width: 50%"><a target="_blank" rel="noopener" href="https://blog.csdn.net/qq_45188736?type=lately">CSDN</a></li>
		        
				</ul>
			</nav>
		</header>				
	</div>
	<div class="mobile-mask" style="display:none" q-show="isShow"></div>
</nav>

      <div id="wrapper" class="body-wrap">
        <div class="menu-l">
          <div class="canvas-wrap">
            <canvas data-colors="#eaeaea" data-sectionHeight="100" data-contentId="js-content" id="myCanvas1" class="anm-canvas"></canvas>
          </div>
          <div id="js-content" class="content-ll">
            
  
    <article id="post-Vue2，生命周期" class="article article-type-post  article-index" itemscope itemprop="blogPost">
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2022/02/28/Vue2%EF%BC%8C%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/">Vue2，生命周期</a>
    </h1>
  

        
        <a href="/blog/2022/02/28/Vue2%EF%BC%8C%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/" class="archive-article-date">
  	<time datetime="2022-02-28T00:52:01.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2022-02-28</time>
</a>
        
      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h1 id="生命周期"><a href="#生命周期" class="headerlink" title="生命周期"></a>生命周期</h1>
        
          <a class="article-more-a" href="/blog/2022/02/28/Vue2%EF%BC%8C%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/#more">more >></a>
        
      

      
    </div>
    <div class="article-info article-info-index">
      
      
	<div class="article-tag tagcloud">
		<i class="icon-price-tags icon"></i>
		<ul class="article-tag-list">
			 
        		<li class="article-tag-list-item">
        			<a href="javascript:void(0)" class="js-tag article-tag-list-link color5">Vue2</a>
        		</li>
      		
		</ul>
	</div>

      

      
        <p class="article-more-link">
          <a class="article-more-a" href="/blog/2022/02/28/Vue2%EF%BC%8C%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/">展开全文 >></a>
        </p>
      

      
      <div class="clearfix"></div>
    </div>
  </div>
</article>

<aside class="wrap-side-operation">
    <div class="mod-side-operation">
        
        <div class="jump-container" id="js-jump-container" style="display:none;">
            <a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
                <i class="icon-font icon-back"></i>
            </a>
            <div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
                <i class="icon-font icon-plane jump-plane"></i>
            </div>
        </div>
        
        
    </div>
</aside>




  
    <article id="post-Vue2，带你看懂插槽的使用" class="article article-type-post  article-index" itemscope itemprop="blogPost">
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2022/02/28/Vue2%EF%BC%8C%E5%B8%A6%E4%BD%A0%E7%9C%8B%E6%87%82%E6%8F%92%E6%A7%BD%E7%9A%84%E4%BD%BF%E7%94%A8/">Vue2，带你看懂插槽的使用</a>
    </h1>
  

        
        <a href="/blog/2022/02/28/Vue2%EF%BC%8C%E5%B8%A6%E4%BD%A0%E7%9C%8B%E6%87%82%E6%8F%92%E6%A7%BD%E7%9A%84%E4%BD%BF%E7%94%A8/" class="archive-article-date">
  	<time datetime="2022-02-28T00:50:59.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2022-02-28</time>
</a>
        
      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="插槽"><a href="#插槽" class="headerlink" title="插槽"></a>插槽</h2><h3 id="匿名插槽"><a href="#匿名插槽" class="headerlink" title="匿名插槽"></a>匿名插槽</h3><p>匿名插槽会储存html组件标签内匿名的标签和元素。</p>
<p><code>htm</code>l代码如下：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">  <span class="comment">&lt;!-- html --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">father</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">button</span> @<span class="attr">click</span>=<span class="string">&quot;pop&quot;</span>&gt;</span>弹出<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">h1</span>&gt;</span>这是一个h1标签<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">father</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><code>js</code>代码如下：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;template id=<span class="string">&quot;father&quot;</span>&gt;</span><br><span class="line">       <span class="xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="xml">           这是一个Father组件</span></span><br><span class="line"><span class="xml">           <span class="tag">&lt;<span class="name">slot</span> <span class="attr">name</span>=<span class="string">&quot;default&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">slot</span>&gt;</span> //可以简写成<span class="tag">&lt;<span class="name">slot</span>&gt;</span><span class="tag">&lt;/<span class="name">slot</span>&gt;</span>,匿名插槽会储存默认的所有元素</span></span><br><span class="line"><span class="xml">       <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">   &lt;/template&gt;</span><br></pre></td></tr></table></figure>



<h3 id="具名插槽"><a href="#具名插槽" class="headerlink" title="具名插槽"></a>具名插槽</h3><p>只能放具体的name对应的标签元素，并且最终渲染取决于模板标签内的具名插槽顺序。</p>
<p><code>htm</code>l代码如下：</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">father</span>&gt;</span></span><br><span class="line">         <span class="comment">&lt;!-- 给插槽取名字 --&gt;</span></span><br><span class="line">         <span class="tag">&lt;<span class="name">h4</span> <span class="attr">slot</span>=<span class="string">&quot;wgd&quot;</span>&gt;</span>我是wgd<span class="tag">&lt;/<span class="name">h4</span>&gt;</span></span><br><span class="line">         <span class="tag">&lt;<span class="name">h1</span> <span class="attr">slot</span>=<span class="string">&quot;h1&quot;</span>&gt;</span>这是一个h1标签<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">         <span class="tag">&lt;<span class="name">h2</span>&gt;</span>这是一个h2 标签<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span><br><span class="line">         <span class="tag">&lt;<span class="name">h3</span>&gt;</span>这是一个h3 标签<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span><br><span class="line">     <span class="tag">&lt;/<span class="name">father</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><code>js</code>代码如下：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&lt;template id=<span class="string">&quot;father&quot;</span>&gt;</span><br><span class="line">      <span class="xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="xml">          这是一个Father组件</span></span><br><span class="line"><span class="xml">              <span class="comment">&lt;!-- 元素的位置由template中的具名插槽的摆放位置有关 --&gt;</span></span></span><br><span class="line"><span class="xml">          <span class="tag">&lt;<span class="name">slot</span> <span class="attr">name</span>=<span class="string">&quot;h1&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">slot</span>&gt;</span></span></span><br><span class="line"><span class="xml">          <span class="tag">&lt;<span class="name">slot</span> <span class="attr">name</span>=<span class="string">&quot;default&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">slot</span>&gt;</span></span></span><br><span class="line"><span class="xml">          <span class="tag">&lt;<span class="name">slot</span> <span class="attr">name</span>=<span class="string">&quot;wgd&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">slot</span>&gt;</span></span></span><br><span class="line"><span class="xml"></span></span><br><span class="line"><span class="xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">  &lt;/template&gt;</span><br></pre></td></tr></table></figure>

<p>效果图如下：</p>
<p><img src="https://img-blog.csdnimg.cn/6ec3d8a8990d4f30858b0db915ee8ef7.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA546b5Y2h5be05Y2h55qE6YCg,size_11,color_FFFFFF,t_70,g_se,x_16#pic_center" alt="在这里插入图片描述"></p>
<h3 id="作用域插槽"><a href="#作用域插槽" class="headerlink" title="作用域插槽"></a>作用域插槽</h3><ul>
<li>在讲解作用域插槽之前我们需要注意到插槽的一个属性，就是它可以访问当前组件父组件。这一点类似<code>$parent</code>。我们来看下一段代码：</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line">&lt;body&gt;</span><br><span class="line">    <span class="xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span></span><br><span class="line"><span class="xml">     <span class="tag">&lt;<span class="name">father</span>&gt;</span><span class="tag">&lt;/<span class="name">father</span>&gt;</span></span></span><br><span class="line"><span class="xml"></span></span><br><span class="line"><span class="xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"></span><br><span class="line">    &lt;!-- 各个模板的书写 --&gt;</span><br><span class="line">    <span class="xml"><span class="tag">&lt;<span class="name">template</span> <span class="attr">id</span>=<span class="string">&quot;son&quot;</span>&gt;</span></span></span><br><span class="line"><span class="xml">        <span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="xml">            Son</span></span><br><span class="line"><span class="xml">            <span class="tag">&lt;<span class="name">slot</span>&gt;</span><span class="tag">&lt;/<span class="name">slot</span>&gt;</span> </span></span><br><span class="line"><span class="xml">            <span class="comment">&lt;!-- 这里是插槽，用来接收元素和标签 --&gt;</span></span></span><br><span class="line"><span class="xml">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="xml"></span></span><br><span class="line"><span class="xml">    <span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"></span><br><span class="line">    <span class="xml"><span class="tag">&lt;<span class="name">template</span> <span class="attr">id</span>=<span class="string">&quot;father&quot;</span>&gt;</span></span></span><br><span class="line"><span class="xml">        <span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="xml">            Father</span></span><br><span class="line"><span class="xml">            <span class="tag">&lt;<span class="name">son</span>&gt;</span></span></span><br><span class="line"><span class="xml">                &#123;&#123;money&#125;&#125;  </span></span><br><span class="line"><span class="xml">                <span class="comment">&lt;!-- 这里写了元素，money虽然写在son标签内但是却是像father组件获取的 --&gt;</span></span></span><br><span class="line"><span class="xml">            <span class="tag">&lt;/<span class="name">son</span>&gt;</span></span></span><br><span class="line"><span class="xml"></span></span><br><span class="line"><span class="xml">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="xml">    <span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line">    <span class="xml"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;../node_modules/vue/dist/vue.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line">    <span class="xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="javascript"></span></span></span><br><span class="line"><span class="javascript"><span class="xml">        <span class="keyword">let</span> son = &#123;</span></span></span><br><span class="line"><span class="javascript"><span class="xml">            <span class="attr">template</span>: <span class="string">&#x27;#son&#x27;</span></span></span></span><br><span class="line"><span class="javascript"><span class="xml">        &#125;</span></span></span><br><span class="line"><span class="javascript"><span class="xml"></span></span></span><br><span class="line"><span class="javascript"><span class="xml"></span></span></span><br><span class="line"><span class="javascript"><span class="xml">        <span class="keyword">let</span> father = &#123;</span></span></span><br><span class="line"><span class="javascript"><span class="xml">            <span class="attr">template</span>: <span class="string">&#x27;#father&#x27;</span>,</span></span></span><br><span class="line"><span class="javascript"><span class="xml">            <span class="attr">components</span>: &#123;</span></span></span><br><span class="line"><span class="javascript"><span class="xml">                son</span></span></span><br><span class="line"><span class="javascript"><span class="xml">            &#125;,</span></span></span><br><span class="line"><span class="javascript"><span class="xml">            <span class="function"><span class="title">data</span>(<span class="params"></span>)</span> &#123;</span></span></span><br><span class="line"><span class="javascript"><span class="xml">                <span class="keyword">return</span> &#123;</span></span></span><br><span class="line"><span class="javascript"><span class="xml">                    <span class="attr">money</span>: <span class="number">111234</span></span></span></span><br><span class="line"><span class="javascript"><span class="xml">                &#125;</span></span></span><br><span class="line"><span class="javascript"><span class="xml">            &#125;</span></span></span><br><span class="line"><span class="javascript"><span class="xml"></span></span></span><br><span class="line"><span class="javascript"><span class="xml">        &#125;</span></span></span><br><span class="line"><span class="javascript"><span class="xml"></span></span></span><br><span class="line"><span class="javascript"><span class="xml">        <span class="keyword">const</span> app = <span class="keyword">new</span> Vue(&#123;</span></span></span><br><span class="line"><span class="javascript"><span class="xml">            <span class="attr">el</span>: <span class="string">&#x27;#app&#x27;</span>,</span></span></span><br><span class="line"><span class="javascript"><span class="xml">            <span class="attr">components</span>: &#123;</span></span></span><br><span class="line"><span class="javascript"><span class="xml">                father,</span></span></span><br><span class="line"><span class="javascript"><span class="xml">              </span></span></span><br><span class="line"><span class="javascript"><span class="xml">            &#125;</span></span></span><br><span class="line"><span class="javascript"><span class="xml">        &#125;)</span></span></span><br><span class="line"><span class="javascript"><span class="xml">    </span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line">&lt;/body&gt;</span><br></pre></td></tr></table></figure>

<p>效果图如下：</p>
<p><img src="https://img-blog.csdnimg.cn/ae44d802101a49a58c9efe9b0150772c.png#pic_center" alt="在这里插入图片描述"></p>
<p>可以看到father组件中的data已经渲染出来，所以插槽可以访问当前组件的父亲组件。如果没有父亲组件则访问Vue实例。</p>
<ul>
<li>好的，那么我们继续来看作用域插槽，我理解它改变了插槽原有的访问父亲组件的属性，现有的属性由当前组件以及自定义获得。使用方法如下：</li>
</ul>
<p>收先在<code>html</code>的组件标签中我们添加 <code>v-slot=&#39;自定义对象&#39;</code></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">mynav</span> <span class="attr">v-slot</span>=<span class="string">&quot;myscope&quot;</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!-- v-slot接收 --&gt;</span></span><br><span class="line">            &#123;&#123;myscope.color&#125;&#125;</span><br><span class="line">            <span class="tag">&lt;<span class="name">h1</span> <span class="attr">:style</span>=<span class="string">&quot;&#123;color:myscope.color&#125;&quot;</span>&gt;</span>这是一个h1标签<span class="tag">&lt;/<span class="name">h1</span>&gt;</span> //注意这里接收到了传递过来的color属性</span><br><span class="line">        <span class="tag">&lt;/<span class="name">mynav</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>紧接着，我们想利用插槽传递什么属性需要在插槽中写出，使用方法如下：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">&lt;script&gt;</span><br><span class="line">       <span class="keyword">let</span> mynav = &#123;</span><br><span class="line">           <span class="attr">template</span>: <span class="string">&quot;&lt;div&gt;&lt;slot :color=&#x27;color&#x27;&gt;&lt;/slot&gt;&lt;/div&gt;&quot;</span>,  <span class="comment">//注意这里传递了color属性</span></span><br><span class="line">           <span class="function"><span class="title">data</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">               <span class="keyword">return</span> &#123;</span><br><span class="line">                   <span class="attr">color</span>: <span class="string">&quot;red&quot;</span></span><br><span class="line">               &#125;</span><br><span class="line">           &#125;</span><br><span class="line">       &#125;</span><br><span class="line">       <span class="keyword">const</span> app = <span class="keyword">new</span> Vue(&#123;</span><br><span class="line">           <span class="attr">el</span>: <span class="string">&#x27;#app&#x27;</span>,</span><br><span class="line">           <span class="attr">data</span>: &#123;</span><br><span class="line">               <span class="comment">// color: &quot;red&quot;</span></span><br><span class="line">           &#125;,</span><br><span class="line">           <span class="attr">components</span>: &#123;</span><br><span class="line">               mynav</span><br><span class="line">           &#125;</span><br><span class="line">       &#125;)</span><br><span class="line">   &lt;/script&gt;</span><br></pre></td></tr></table></figure>

      

      
    </div>
    <div class="article-info article-info-index">
      
      
	<div class="article-tag tagcloud">
		<i class="icon-price-tags icon"></i>
		<ul class="article-tag-list">
			 
        		<li class="article-tag-list-item">
        			<a href="javascript:void(0)" class="js-tag article-tag-list-link color5">Vue2</a>
        		</li>
      		
		</ul>
	</div>

      

      
        <p class="article-more-link">
          <a class="article-more-a" href="/blog/2022/02/28/Vue2%EF%BC%8C%E5%B8%A6%E4%BD%A0%E7%9C%8B%E6%87%82%E6%8F%92%E6%A7%BD%E7%9A%84%E4%BD%BF%E7%94%A8/">展开全文 >></a>
        </p>
      

      
      <div class="clearfix"></div>
    </div>
  </div>
</article>

<aside class="wrap-side-operation">
    <div class="mod-side-operation">
        
        <div class="jump-container" id="js-jump-container" style="display:none;">
            <a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
                <i class="icon-font icon-back"></i>
            </a>
            <div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
                <i class="icon-font icon-plane jump-plane"></i>
            </div>
        </div>
        
        
    </div>
</aside>




  
    <article id="post-Vue2，用实例带你看懂自定义组件的v-model" class="article article-type-post  article-index" itemscope itemprop="blogPost">
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2022/02/28/Vue2%EF%BC%8C%E7%94%A8%E5%AE%9E%E4%BE%8B%E5%B8%A6%E4%BD%A0%E7%9C%8B%E6%87%82%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E7%9A%84v-model/">Vue2，用实例带你看懂自定义组件的v-model</a>
    </h1>
  

        
        <a href="/blog/2022/02/28/Vue2%EF%BC%8C%E7%94%A8%E5%AE%9E%E4%BE%8B%E5%B8%A6%E4%BD%A0%E7%9C%8B%E6%87%82%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E7%9A%84v-model/" class="archive-article-date">
  	<time datetime="2022-02-28T00:50:17.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2022-02-28</time>
</a>
        
      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h3 id="自定义组件的v-model"><a href="#自定义组件的v-model" class="headerlink" title="自定义组件的v-model"></a>自定义组件的v-model</h3>
        
          <a class="article-more-a" href="/blog/2022/02/28/Vue2%EF%BC%8C%E7%94%A8%E5%AE%9E%E4%BE%8B%E5%B8%A6%E4%BD%A0%E7%9C%8B%E6%87%82%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E7%9A%84v-model/#more">more >></a>
        
      

      
    </div>
    <div class="article-info article-info-index">
      
      
	<div class="article-tag tagcloud">
		<i class="icon-price-tags icon"></i>
		<ul class="article-tag-list">
			 
        		<li class="article-tag-list-item">
        			<a href="javascript:void(0)" class="js-tag article-tag-list-link color5">Vue2</a>
        		</li>
      		
		</ul>
	</div>

      

      
        <p class="article-more-link">
          <a class="article-more-a" href="/blog/2022/02/28/Vue2%EF%BC%8C%E7%94%A8%E5%AE%9E%E4%BE%8B%E5%B8%A6%E4%BD%A0%E7%9C%8B%E6%87%82%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E7%9A%84v-model/">展开全文 >></a>
        </p>
      

      
      <div class="clearfix"></div>
    </div>
  </div>
</article>

<aside class="wrap-side-operation">
    <div class="mod-side-operation">
        
        <div class="jump-container" id="js-jump-container" style="display:none;">
            <a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
                <i class="icon-font icon-back"></i>
            </a>
            <div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
                <i class="icon-font icon-plane jump-plane"></i>
            </div>
        </div>
        
        
    </div>
</aside>




  
    <article id="post-Vue2，局部组件component的用方法" class="article article-type-post  article-index" itemscope itemprop="blogPost">
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2022/02/28/Vue2%EF%BC%8C%E5%B1%80%E9%83%A8%E7%BB%84%E4%BB%B6component%E7%9A%84%E7%94%A8%E6%96%B9%E6%B3%95/">Vue2，局部组件component的用方法</a>
    </h1>
  

        
        <a href="/blog/2022/02/28/Vue2%EF%BC%8C%E5%B1%80%E9%83%A8%E7%BB%84%E4%BB%B6component%E7%9A%84%E7%94%A8%E6%96%B9%E6%B3%95/" class="archive-article-date">
  	<time datetime="2022-02-28T00:49:46.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2022-02-28</time>
</a>
        
      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h3 id="局部组件component的用方法"><a href="#局部组件component的用方法" class="headerlink" title="局部组件component的用方法"></a>局部组件component的用方法</h3>
        
          <a class="article-more-a" href="/blog/2022/02/28/Vue2%EF%BC%8C%E5%B1%80%E9%83%A8%E7%BB%84%E4%BB%B6component%E7%9A%84%E7%94%A8%E6%96%B9%E6%B3%95/#more">more >></a>
        
      

      
    </div>
    <div class="article-info article-info-index">
      
      
	<div class="article-tag tagcloud">
		<i class="icon-price-tags icon"></i>
		<ul class="article-tag-list">
			 
        		<li class="article-tag-list-item">
        			<a href="javascript:void(0)" class="js-tag article-tag-list-link color5">Vue2</a>
        		</li>
      		
		</ul>
	</div>

      

      
        <p class="article-more-link">
          <a class="article-more-a" href="/blog/2022/02/28/Vue2%EF%BC%8C%E5%B1%80%E9%83%A8%E7%BB%84%E4%BB%B6component%E7%9A%84%E7%94%A8%E6%96%B9%E6%B3%95/">展开全文 >></a>
        </p>
      

      
      <div class="clearfix"></div>
    </div>
  </div>
</article>

<aside class="wrap-side-operation">
    <div class="mod-side-operation">
        
        <div class="jump-container" id="js-jump-container" style="display:none;">
            <a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
                <i class="icon-font icon-back"></i>
            </a>
            <div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
                <i class="icon-font icon-plane jump-plane"></i>
            </div>
        </div>
        
        
    </div>
</aside>




  
    <article id="post-Vue2，mixin混入语法" class="article article-type-post  article-index" itemscope itemprop="blogPost">
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2022/02/28/Vue2%EF%BC%8Cmixin%E6%B7%B7%E5%85%A5%E8%AF%AD%E6%B3%95/">Vue2，mixin混入语法</a>
    </h1>
  

        
        <a href="/blog/2022/02/28/Vue2%EF%BC%8Cmixin%E6%B7%B7%E5%85%A5%E8%AF%AD%E6%B3%95/" class="archive-article-date">
  	<time datetime="2022-02-28T00:47:44.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2022-02-28</time>
</a>
        
      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="mixin-混入语法"><a href="#mixin-混入语法" class="headerlink" title="mixin 混入语法"></a>mixin 混入语法</h2><p>混入语法中的生命周期执行会加入到实例调用的实例当中，data和methods会遵从实例中的data和methods。<br>
        
          <a class="article-more-a" href="/blog/2022/02/28/Vue2%EF%BC%8Cmixin%E6%B7%B7%E5%85%A5%E8%AF%AD%E6%B3%95/#more">more >></a>
        
      

      
    </div>
    <div class="article-info article-info-index">
      
      
	<div class="article-tag tagcloud">
		<i class="icon-price-tags icon"></i>
		<ul class="article-tag-list">
			 
        		<li class="article-tag-list-item">
        			<a href="javascript:void(0)" class="js-tag article-tag-list-link color5">Vue2</a>
        		</li>
      		
		</ul>
	</div>

      

      
        <p class="article-more-link">
          <a class="article-more-a" href="/blog/2022/02/28/Vue2%EF%BC%8Cmixin%E6%B7%B7%E5%85%A5%E8%AF%AD%E6%B3%95/">展开全文 >></a>
        </p>
      

      
      <div class="clearfix"></div>
    </div>
  </div>
</article>

<aside class="wrap-side-operation">
    <div class="mod-side-operation">
        
        <div class="jump-container" id="js-jump-container" style="display:none;">
            <a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
                <i class="icon-font icon-back"></i>
            </a>
            <div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
                <i class="icon-font icon-plane jump-plane"></i>
            </div>
        </div>
        
        
    </div>
</aside>




  
    <article id="post-Vue2，过滤器的使用详解" class="article article-type-post  article-index" itemscope itemprop="blogPost">
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2022/02/28/Vue2%EF%BC%8C%E8%BF%87%E6%BB%A4%E5%99%A8%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%A6%E8%A7%A3/">Vue2，过滤器的使用详解</a>
    </h1>
  

        
        <a href="/blog/2022/02/28/Vue2%EF%BC%8C%E8%BF%87%E6%BB%A4%E5%99%A8%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%A6%E8%A7%A3/" class="archive-article-date">
  	<time datetime="2022-02-28T00:47:12.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2022-02-28</time>
</a>
        
      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h3 id="过滤器"><a href="#过滤器" class="headerlink" title="过滤器"></a>过滤器</h3><p>Vue.js 允许你自定义过滤器，可被用于一些常见的文本格式化。过滤器可以用在两个地方：<strong>双花括号插值和 <code>v-bind</code> 表达式</strong> (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部，由“管道”符号指示：<br>
        
          <a class="article-more-a" href="/blog/2022/02/28/Vue2%EF%BC%8C%E8%BF%87%E6%BB%A4%E5%99%A8%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%A6%E8%A7%A3/#more">more >></a>
        
      

      
    </div>
    <div class="article-info article-info-index">
      
      
	<div class="article-tag tagcloud">
		<i class="icon-price-tags icon"></i>
		<ul class="article-tag-list">
			 
        		<li class="article-tag-list-item">
        			<a href="javascript:void(0)" class="js-tag article-tag-list-link color5">Vue2</a>
        		</li>
      		
		</ul>
	</div>

      

      
        <p class="article-more-link">
          <a class="article-more-a" href="/blog/2022/02/28/Vue2%EF%BC%8C%E8%BF%87%E6%BB%A4%E5%99%A8%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%A6%E8%A7%A3/">展开全文 >></a>
        </p>
      

      
      <div class="clearfix"></div>
    </div>
  </div>
</article>

<aside class="wrap-side-operation">
    <div class="mod-side-operation">
        
        <div class="jump-container" id="js-jump-container" style="display:none;">
            <a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
                <i class="icon-font icon-back"></i>
            </a>
            <div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
                <i class="icon-font icon-plane jump-plane"></i>
            </div>
        </div>
        
        
    </div>
</aside>




  
    <article id="post-Vue2，plugin插件的使用详解" class="article article-type-post  article-index" itemscope itemprop="blogPost">
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2022/02/28/Vue2%EF%BC%8Cplugin%E6%8F%92%E4%BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%A6%E8%A7%A3/">Vue2，plugin插件的使用详解</a>
    </h1>
  

        
        <a href="/blog/2022/02/28/Vue2%EF%BC%8Cplugin%E6%8F%92%E4%BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%A6%E8%A7%A3/" class="archive-article-date">
  	<time datetime="2022-02-28T00:46:34.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2022-02-28</time>
</a>
        
      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h3 id="plugin插件的使用"><a href="#plugin插件的使用" class="headerlink" title="plugin插件的使用"></a>plugin插件的使用</h3>
        
          <a class="article-more-a" href="/blog/2022/02/28/Vue2%EF%BC%8Cplugin%E6%8F%92%E4%BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%A6%E8%A7%A3/#more">more >></a>
        
      

      
    </div>
    <div class="article-info article-info-index">
      
      
	<div class="article-tag tagcloud">
		<i class="icon-price-tags icon"></i>
		<ul class="article-tag-list">
			 
        		<li class="article-tag-list-item">
        			<a href="javascript:void(0)" class="js-tag article-tag-list-link color5">Vue2</a>
        		</li>
      		
		</ul>
	</div>

      

      
        <p class="article-more-link">
          <a class="article-more-a" href="/blog/2022/02/28/Vue2%EF%BC%8Cplugin%E6%8F%92%E4%BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%A6%E8%A7%A3/">展开全文 >></a>
        </p>
      

      
      <div class="clearfix"></div>
    </div>
  </div>
</article>

<aside class="wrap-side-operation">
    <div class="mod-side-operation">
        
        <div class="jump-container" id="js-jump-container" style="display:none;">
            <a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
                <i class="icon-font icon-back"></i>
            </a>
            <div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
                <i class="icon-font icon-plane jump-plane"></i>
            </div>
        </div>
        
        
    </div>
</aside>




  
    <article id="post-Vue2-带你探秘-attrs和-listeners" class="article article-type-post  article-index" itemscope itemprop="blogPost">
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2022/02/28/Vue2-%E5%B8%A6%E4%BD%A0%E6%8E%A2%E7%A7%98-attrs%E5%92%8C-listeners/">Vue2,带你探秘 $ attrs和 $ listeners</a>
    </h1>
  

        
        <a href="/blog/2022/02/28/Vue2-%E5%B8%A6%E4%BD%A0%E6%8E%A2%E7%A7%98-attrs%E5%92%8C-listeners/" class="archive-article-date">
  	<time datetime="2022-02-28T00:45:39.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2022-02-28</time>
</a>
        
      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h1 id="带你探秘-attrs和-listeners"><a href="#带你探秘-attrs和-listeners" class="headerlink" title="带你探秘$ attrs和$ listeners"></a>带你探秘$ attrs和$ listeners</h1>
        
          <a class="article-more-a" href="/blog/2022/02/28/Vue2-%E5%B8%A6%E4%BD%A0%E6%8E%A2%E7%A7%98-attrs%E5%92%8C-listeners/#more">more >></a>
        
      

      
    </div>
    <div class="article-info article-info-index">
      
      
	<div class="article-tag tagcloud">
		<i class="icon-price-tags icon"></i>
		<ul class="article-tag-list">
			 
        		<li class="article-tag-list-item">
        			<a href="javascript:void(0)" class="js-tag article-tag-list-link color5">Vue2</a>
        		</li>
      		
		</ul>
	</div>

      

      
        <p class="article-more-link">
          <a class="article-more-a" href="/blog/2022/02/28/Vue2-%E5%B8%A6%E4%BD%A0%E6%8E%A2%E7%A7%98-attrs%E5%92%8C-listeners/">展开全文 >></a>
        </p>
      

      
      <div class="clearfix"></div>
    </div>
  </div>
</article>

<aside class="wrap-side-operation">
    <div class="mod-side-operation">
        
        <div class="jump-container" id="js-jump-container" style="display:none;">
            <a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
                <i class="icon-font icon-back"></i>
            </a>
            <div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
                <i class="icon-font icon-plane jump-plane"></i>
            </div>
        </div>
        
        
    </div>
</aside>




  
    <article id="post-Vue2-一起探秘VueRouer-3x" class="article article-type-post  article-index" itemscope itemprop="blogPost">
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2022/02/28/Vue2-%E4%B8%80%E8%B5%B7%E6%8E%A2%E7%A7%98VueRouer-3x/">Vue2,一起探秘VueRouer 3x</a>
    </h1>
  

        
        <a href="/blog/2022/02/28/Vue2-%E4%B8%80%E8%B5%B7%E6%8E%A2%E7%A7%98VueRouer-3x/" class="archive-article-date">
  	<time datetime="2022-02-28T00:37:42.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2022-02-28</time>
</a>
        
      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h1 id="Vue2，VueRouter的基本使用"><a href="#Vue2，VueRouter的基本使用" class="headerlink" title="Vue2，VueRouter的基本使用"></a>Vue2，VueRouter的基本使用</h1><h2 id="VueRouter的下载安装"><a href="#VueRouter的下载安装" class="headerlink" title="VueRouter的下载安装"></a>VueRouter的下载安装</h2><ul>
<li><p>Vue-router 要单独引用，版本3.x以上</p>
</li>
<li><p>需要先引用Vue再引用Vue Router</p>
</li>
</ul>
<h2 id="VueRouter创建的五个步骤"><a href="#VueRouter创建的五个步骤" class="headerlink" title="VueRouter创建的五个步骤"></a>VueRouter创建的五个步骤</h2>
        
          <a class="article-more-a" href="/blog/2022/02/28/Vue2-%E4%B8%80%E8%B5%B7%E6%8E%A2%E7%A7%98VueRouer-3x/#more">more >></a>
        
      

      
    </div>
    <div class="article-info article-info-index">
      
      
	<div class="article-tag tagcloud">
		<i class="icon-price-tags icon"></i>
		<ul class="article-tag-list">
			 
        		<li class="article-tag-list-item">
        			<a href="javascript:void(0)" class="js-tag article-tag-list-link color5">Vue2</a>
        		</li>
      		
		</ul>
	</div>

      

      
        <p class="article-more-link">
          <a class="article-more-a" href="/blog/2022/02/28/Vue2-%E4%B8%80%E8%B5%B7%E6%8E%A2%E7%A7%98VueRouer-3x/">展开全文 >></a>
        </p>
      

      
      <div class="clearfix"></div>
    </div>
  </div>
</article>

<aside class="wrap-side-operation">
    <div class="mod-side-operation">
        
        <div class="jump-container" id="js-jump-container" style="display:none;">
            <a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
                <i class="icon-font icon-back"></i>
            </a>
            <div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
                <i class="icon-font icon-plane jump-plane"></i>
            </div>
        </div>
        
        
    </div>
</aside>




  
    <article id="post-面试宝典" class="article article-type-post  article-index" itemscope itemprop="blogPost">
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2022/02/25/%E9%9D%A2%E8%AF%95%E5%AE%9D%E5%85%B8/">面试宝典</a>
    </h1>
  

        
        <a href="/blog/2022/02/25/%E9%9D%A2%E8%AF%95%E5%AE%9D%E5%85%B8/" class="archive-article-date">
  	<time datetime="2022-02-25T03:13:29.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2022-02-25</time>
</a>
        
      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h1 id="北游国际面试题总结"><a href="#北游国际面试题总结" class="headerlink" title="北游国际面试题总结"></a>北游国际面试题总结</h1><blockquote>
<p>人事部分</p>
<p>html、css</p>
<p>javascript</p>
<p>网络请求</p>
</blockquote>
<h1 id="一、人事部分"><a href="#一、人事部分" class="headerlink" title="一、人事部分"></a>一、人事部分</h1><ul>
<li><p>参考网址</p>
<p><a target="_blank" rel="noopener" href="https://juejin.cn/post/7010948744560508941">https://juejin.cn/post/7010948744560508941</a></p>
</li>
<li><p>自我介绍</p>
<p><strong>模板一:</strong></p>
<p>你好，我叫XXX,有XX年工作经验，来应聘前端开发工程师这一岗位。我之前在XXX工作过，期间主要负责前端项目、app和微信小程序的开发和维护工作。参与开发的项目有XX个，独自开发的项目的有XX个。在此期间，商城/交友/工具/直播/类项目做的比较多。其中印象最深的是XX项目，因为是第一个独立开发的项目/学到知识最多的项目/最难的项目/最近才做好的项目/开发周期最长的项目。我在招聘网上看到咱们公司的招聘信息，感觉自身跟公司比较契合，希望能够加入公司，成为公司的一员。</p>
<p><strong>模板二:</strong></p>
<p><strong>注意：语速不能过慢不能过快，不要边想边说，一定是把自我介绍想好，一般人的语速是在80-160之间</strong></p>
</li>
<li><p>公司有几个人，部门构成是什么，你所属哪个部门，有几个人</p>
<p>甲方 掏钱  18000<br>  –IT劳务外派公司 15000 - 3000<br>乙方  –  外包公司<br>  12个人<br>  人事部 1<br>  财务部 1<br>  技术部 7 1个 UI1个 后端2（后端的某一个人员）  前端2  1个ios/ 1android<br>  市场部 4 2个  4个项目 * 2-8w = 20w</p>
<pre><code>     15% * 50 = 7.5w
     UI 5k+14k+14K + 8k = 4.1
     
</code></pre>
<p>  政府 – 人脉 </p>
<p>  产品经理、UI、后端、前端、CTO（技术总监）<br>  根据客户需求 -&gt;  墨刀 -&gt; 原型图<br>  UI  : 设计图、切。。。<br>  后端: java、PHP、Python、Ruby、Golang<br>  前端: 页面 </p>
</li>
<li><p>.为什么离职</p>
</li>
</ul>
<p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0cde680055554c689d970df11b969dc9~tplv-k3u1fbpfcp-watermark.awebp" alt="img"></p>
<h1 id="二、html部分"><a href="#二、html部分" class="headerlink" title="二、html部分"></a>二、html部分</h1><h2 id="2-1-HTMl5新增特性有哪些？"><a href="#2-1-HTMl5新增特性有哪些？" class="headerlink" title="2.1  HTMl5新增特性有哪些？"></a>2.1  HTMl5新增特性有哪些？</h2><p>(1) 新增了语义化标签</p>
<p>(2) 新增了音频（audio）视频（video）标签</p>
<p>(3) 新增了canvas和svg绘图</p>
<p>(4) 新增了地理定位（navigator.geolocation）</p>
<p>(5) 新增了拖拽API (drapable)</p>
<p>(6) 新增了多线程技术web worker </p>
<p>(7) 新增了即时通讯web socket</p>
<h2 id="2-2-CSS3-新增特性"><a href="#2-2-CSS3-新增特性" class="headerlink" title="2.2 CSS3 新增特性"></a>2.2 CSS3 新增特性</h2><p>(1) 增加了transition渐变animation动画</p>
<p>(2) 选择器、阴影、弹性布局flex</p>
<p>(3) 媒体查询等</p>
<h2 id="2-3-W3C标准有哪些？（可以不会）"><a href="#2-3-W3C标准有哪些？（可以不会）" class="headerlink" title="2.3 W3C标准有哪些？（可以不会）"></a>2.3 W3C标准有哪些？（可以不会）</h2><p>(1) 标准分为三个层面，结构(html)、行为(js)、表现(css)</p>
<p>(2) 标准有:</p>
<p>(3) 文档类型需要声明（DOCTYPE）</p>
<p>(4) 编码格式需要声明 <meta charset="utf-8"></p>
<p>(5) javascript代码需要定义</p>
<p>(6) &lt;script language=”javascript” type = ”text/javascript”&gt;</script></p>
<p>(7) css代码需要定义</p>
<p>(8) <style type="text/css"></style></p>
<p>(9) 标签名字和标签内部属性名字小写等</p>
<h2 id="2-4-你遇到哪些浏览器兼容问题？您怎么处理浏览器兼容性问题的"><a href="#2-4-你遇到哪些浏览器兼容问题？您怎么处理浏览器兼容性问题的" class="headerlink" title="2.4 你遇到哪些浏览器兼容问题？您怎么处理浏览器兼容性问题的"></a>2.4 你遇到哪些浏览器兼容问题？您怎么处理浏览器兼容性问题的</h2><p>参考地址: <a target="_blank" rel="noopener" href="https://www.cnblogs.com/wxf-h/p/10513342.html">https://www.cnblogs.com/wxf-h/p/10513342.html</a></p>
<ul>
<li><p><strong>css兼容性问题</strong></p>
<ol>
<li>cursor:hand VS cursor:pointer</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">firefox 不支持hand，但ie支持 pointer</span><br><span class="line">解决方法:统一使用pointer</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>innerText在IE中能正常工作，但在FireFox中却不行</li>
<li>CSS透明</li>
<li>盒子模型</li>
<li>块属性标签float后，又有横行的margin情况下，在IE6显示margin比设置的大</li>
<li>图片默认有间距</li>
<li>万能清除浮动</li>
<li>IE捉迷藏的问题</li>
<li>溢出显示省略号</li>
<li>IE6下图片下有空隙产生</li>
<li>超链接访问过后hover样式就不出现的问题</li>
</ol>
</li>
<li><p><strong>JS里面的兼容性问题</strong><br>1.const问题</p>
<pre><code>说明:Firefox下,可以使用const关键字或var关键字来定义常量;IE下,只能使用var关键字来定义常量. 
</code></pre>
<p>​    <strong>解决方法：统一使用var关键字来定义常量.</strong><br>2.event.srcElement问题<br>​    说明：IE下，event对象有srcElement属性，但是没有target属性；Firefox下，even对象有target属性，但是没有srcElement属性。<br>​    <strong>解决方法：使用srcObj =event.srcElement ?event.srcElement : event.target;</strong><br>3.事件绑定<br>   IE：dom.attachEvent();<br>   其他浏览器：dom.addEventListener();<br>   标准浏览器采用事件捕获的方式对应IE的事件冒泡机制（即标准由最外元素至最内元素或者IE由最内元素到      最外元素）最后标准方亦觉得IE这方面的比较合理，所以便将事件冒泡纳入了标准，这也addEventListener第三个参数的由来，而且事件冒泡作为了默认值。</p>
<ol start="4">
<li>ajax略有不同<br>IE:ActiveXObject<br> 其他：xmlHttpReuest</li>
</ol>
</li>
</ul>
<h2 id="2-5-CSS伪类选择器有哪些-（会一点就行了）"><a href="#2-5-CSS伪类选择器有哪些-（会一点就行了）" class="headerlink" title="2.5 CSS伪类选择器有哪些?（会一点就行了）"></a>2.5 CSS伪类选择器有哪些?（会一点就行了）</h2><p>(1) :before         在…之前 </p>
<p>(2) :after      在…之后</p>
<p>(3) :active      点击</p>
<p>(4) :hover      鼠标悬停</p>
<p>(5) :first-letter  所有文字当中的第一个</p>
<p>(6) :first-line      所选元素当中的第一行</p>
<p>(7) :first-child  第一个子元素</p>
<p>(8) :nth-child()  获取子元素</p>
<p>(9) :nth-of-type  获取指定类型的子元素</p>
<p>等等几十个</p>
<h2 id="2-6-常用的适配手段有哪些"><a href="#2-6-常用的适配手段有哪些" class="headerlink" title="2.6 常用的适配手段有哪些"></a>2.6 常用的适配手段有哪些</h2><p>1.媒体查询</p>
<p>2.弹性布局</p>
<p>3.使用各种UI框架，UI框架一般都做了适配工作</p>
<p>4.手淘适配方案 （使用flexiable插件完成适配）</p>
<h2 id="2-7-说说你对flex布局的理解"><a href="#2-7-说说你对flex布局的理解" class="headerlink" title="2.7 说说你对flex布局的理解"></a>2.7 说说你对flex布局的理解</h2><p>参考: <a target="_blank" rel="noopener" href="https://www.cnblogs.com/jpwz/p/12483053.html">https://www.cnblogs.com/jpwz/p/12483053.html</a><br>Flex 是 Flexible Box 的缩写，意为”灵活的盒子”或”弹性的盒子”，所以 flex 布局一般也叫作”弹性布局”。</p>
<ul>
<li>display 属性</li>
<li>flex-direction 属性</li>
<li>flex-wrap 属性</li>
<li>flex-flow</li>
<li>justify-content 属性</li>
<li>align-items 属性</li>
<li>align-content 属性</li>
</ul>
<h2 id="2-8-rem和em、VH、VW、PX的区别"><a href="#2-8-rem和em、VH、VW、PX的区别" class="headerlink" title="2.8 rem和em、VH、VW、PX的区别"></a>2.8 rem和em、VH、VW、PX的区别</h2><p>em是相对于父级标签的字体大小来定义的<br>rem是相对于html标签的字体大小来定义的</p>
<h2 id="2-9-canvas和svg的区别"><a href="#2-9-canvas和svg的区别" class="headerlink" title="2.9 canvas和svg的区别"></a>2.9 canvas和svg的区别</h2><p>都可以用来绘制图形，但是canvas是基于js来绘制的，svg是基于xml来绘制的.SVG绘制出来的是矢量图。</p>
<h2 id="2-10什么是BFC？BFC的布局规则是什么？如何创建BFC？BFC应用？"><a href="#2-10什么是BFC？BFC的布局规则是什么？如何创建BFC？BFC应用？" class="headerlink" title="2.10什么是BFC？BFC的布局规则是什么？如何创建BFC？BFC应用？"></a>2.10什么是BFC？BFC的布局规则是什么？如何创建BFC？BFC应用？</h2><p><code>BFC</code> 是 <code>Block Formatting Context </code>的缩写，即块格式化上下文。<code>BFC</code>是CSS布局的一个概念，是一个环境，里面的元素不会影响外面的元素。 布局规则：Box是CSS布局的对象和基本单位，页面是由若干个Box组成的。元素的类型和display属性，决定了这个Box的类型。不同类型的Box会参与不同的<code>Formatting Context</code>。 </p>
<p>创建：浮动元素 <code>display：inline-block position:absolute</code> </p>
<p>应用: 1.分属于不同的<code>BFC</code>时,可以防止<code>margin</code>重叠 2.清除内部浮动 3.自适应多栏布局</p>
<h2 id="2-11-BFC的作用"><a href="#2-11-BFC的作用" class="headerlink" title="2.11 BFC的作用"></a>2.11 BFC的作用</h2><p>(1)避免margin重叠<br>(2)清除浮动</p>
<h2 id="2-12-清除浮动的方式有哪些"><a href="#2-12-清除浮动的方式有哪些" class="headerlink" title="2.12 清除浮动的方式有哪些"></a>2.12 清除浮动的方式有哪些</h2><p>(1)浮动元素后新增标签，并且设置属性clear:both ;<br>(2)浮动元素的父标签设置属性overflow:hidden;<br>(3)设置伪类选择器 XX:after{clear:both}</p>
<h2 id="2-13-网站页面常见优化的手段"><a href="#2-13-网站页面常见优化的手段" class="headerlink" title="2.13 网站页面常见优化的手段"></a>2.13 网站页面常见优化的手段</h2><p>(1)优化图片资源的格式（优先级选择webp &gt; jpeg &gt; png &gt; bmp）<br>(2)使用压缩文件 min.js、min.css<br>(3)使用浏览器缓存（cookie ， localStorage）<br>(4)尽量减少请求次数<br>(5)使用懒加载，避免一次性请求过多</p>
<h2 id="2-14-常见的浏览器内核有哪些"><a href="#2-14-常见的浏览器内核有哪些" class="headerlink" title="2.14 常见的浏览器内核有哪些"></a>2.14 常见的浏览器内核有哪些</h2><p><img src="C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210923120048016.png" alt="image-20210923120048016"></p>
<h2 id="2-15-CSS选择器优先级"><a href="#2-15-CSS选择器优先级" class="headerlink" title="2.15 CSS选择器优先级"></a>2.15 CSS选择器优先级</h2><ul>
<li><p>内联样式表的权值为 1000</p>
</li>
<li><p>ID 选择器的权值为 100</p>
</li>
<li><p>Class 类选择器的权值为 10</p>
</li>
<li><p>HTML 标签选择器的权值为 1</p>
<p>通过使用加法计算出来权重的大小</p>
</li>
</ul>
<h2 id="2-16-左右两边固定宽度-（左边固定右边自适应布局）中间自适应-布局实现"><a href="#2-16-左右两边固定宽度-（左边固定右边自适应布局）中间自适应-布局实现" class="headerlink" title="2.16 左右两边固定宽度 （左边固定右边自适应布局）中间自适应  布局实现"></a>2.16 左右两边固定宽度 （左边固定右边自适应布局）中间自适应  布局实现</h2><p>圣杯布局、双飞翼布局</p>
<p>左边固定右边自适应 七种方式</p>
<p><a target="_blank" rel="noopener" href="https://segmentfault.com/a/1190000010698609">https://segmentfault.com/a/1190000010698609</a></p>
<h2 id="2-17-九宫格实现方式"><a href="#2-17-九宫格实现方式" class="headerlink" title="2.17 九宫格实现方式"></a>2.17 九宫格实现方式</h2><ul>
<li>flex布局 （css3）</li>
<li>grid布局 （css3新增）</li>
<li>float</li>
<li>table       （）</li>
</ul>
<p>参考地址：<a target="_blank" rel="noopener" href="https://www.cnblogs.com/sunshq/p/10118425.html">https://www.cnblogs.com/sunshq/p/10118425.html</a></p>
<h2 id="2-18-让一个盒子在父元素的中进行左右垂直居中"><a href="#2-18-让一个盒子在父元素的中进行左右垂直居中" class="headerlink" title="2.18 让一个盒子在父元素的中进行左右垂直居中"></a>2.18 让一个盒子在父元素的中进行左右垂直居中</h2><p>参考地址： <a target="_blank" rel="noopener" href="https://www.cnblogs.com/yingtoumao/p/11541256.html">https://www.cnblogs.com/yingtoumao/p/11541256.html</a></p>
<h2 id="2-19-什么是盒子模型？"><a href="#2-19-什么是盒子模型？" class="headerlink" title="2.19 什么是盒子模型？"></a>2.19 什么是盒子模型？</h2><p>w3c标准盒模型：width+左右内边距+左右边框+左右外边距<br>怪异盒模型：width+左右外边距</p>
<p>Centent-box:标准盒模型<br>Border-box：怪异盒模型</p>
<h2 id="2-20-简述字体图标的原理，动手实现使用-iconfont-实现字体图标的-demo。"><a href="#2-20-简述字体图标的原理，动手实现使用-iconfont-实现字体图标的-demo。" class="headerlink" title="2.20 简述字体图标的原理，动手实现使用 iconfont 实现字体图标的 demo。"></a>2.20 简述字体图标的原理，动手实现使用 iconfont 实现字体图标的 demo。</h2><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 定义font-family */</span></span><br><span class="line"><span class="keyword">@font-face</span> &#123;</span><br><span class="line">    <span class="attribute">font-family</span>: <span class="string">&quot;myiconfont&quot;</span>;</span><br><span class="line">    <span class="attribute">src</span>: <span class="built_in">url</span>(<span class="string">&#x27;./iconfont.woff2&#x27;</span>) <span class="built_in">format</span>(<span class="string">&#x27;woff2&#x27;</span>),</span><br><span class="line">         <span class="built_in">url</span>(<span class="string">&#x27;./iconfont.woff&#x27;</span>) <span class="built_in">format</span>(<span class="string">&#x27;woff&#x27;</span>),</span><br><span class="line">         <span class="built_in">url</span>(<span class="string">&#x27;./iconfont.ttf&#x27;</span>) <span class="built_in">format</span>(<span class="string">&#x27;truetype&#x27;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*  */</span></span><br><span class="line"><span class="selector-attr">[class^=<span class="string">&quot;iconfont&quot;</span>]</span>,</span><br><span class="line"><span class="selector-attr">[class*=<span class="string">&quot; iconfont&quot;</span>]</span> &#123;</span><br><span class="line">    <span class="attribute">font-family</span>: <span class="string">&quot;myiconfont&quot;</span>;</span><br><span class="line">    <span class="attribute">font-style</span>: normal;</span><br><span class="line">    <span class="attribute">font-size</span>: <span class="number">14px</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.icon-star</span><span class="selector-pseudo">::before</span> &#123;</span><br><span class="line">    <span class="attribute">content</span>: <span class="string">&quot;\e616&quot;</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="2-21-浏览器渲染机制、重绘、重排"><a href="#2-21-浏览器渲染机制、重绘、重排" class="headerlink" title="2.21 浏览器渲染机制、重绘、重排"></a>2.21 浏览器渲染机制、重绘、重排</h2><p>网页生成过程：</p>
<ul>
<li><code>HTML</code>被HTML解析器解析成<code>DOM</code> 树</li>
<li><code>css</code>则被css解析器解析成<code>CSSOM </code>树</li>
<li>结合<code>DOM</code>树和<code>CSSOM</code>树，生成一棵渲染树(<code>Render Tree</code>)</li>
<li>生成布局（<code>flow</code>），即将所有渲染树的所有节点进行平面合成</li>
<li>将布局绘制（<code>paint</code>）在屏幕上</li>
</ul>
<p><strong>重排(也称回流):</strong> 当<code>DOM</code>的变化影响了元素的几何信息(<code>DOM</code>对象的位置和尺寸大小)，浏览器需要重新计算元素的几何属性，将其安放在界面中的正确位置，这个过程叫做重排。 触发：</p>
<ol>
<li>添加或者删除可见的DOM元素</li>
<li>元素尺寸改变——边距、填充、边框、宽度和高度</li>
</ol>
<p><strong>重绘：</strong> 当一个元素的外观发生改变，但没有改变布局,重新把元素外观绘制出来的过程，叫做重绘。 触发：</p>
<ul>
<li>改变元素的<code>color、background、box-shadow</code>等属性</li>
</ul>
<p><strong>重排优化建议：</strong></p>
<ol>
<li>分离读写操作</li>
<li>样式集中修改</li>
<li>缓存需要修改的<code>DOM</code>元素</li>
<li>尽量只修改<code>position：absolute</code>或<code>fixed</code>元素，对其他元素影响不大</li>
<li>动画开始<code>GPU</code>加速，<code>translate</code>使用<code>3D</code>变化</li>
</ol>
<p><code>transform</code> 不重绘，不回流 是因为<code>transform</code>属于合成属性，对合成属性进行<code>transition/animate</code>动画时，将会创建一个合成层。这使得动画元素在一个独立的层中进行渲染。当元素的内容没有发生改变，就没有必要进行重绘。浏览器会通过重新复合来创建动画帧。</p>
<h2 id="2-22-css-怎么开启硬件加速-GPU-加速"><a href="#2-22-css-怎么开启硬件加速-GPU-加速" class="headerlink" title="2.22 css 怎么开启硬件加速(GPU 加速)"></a>2.22 css 怎么开启硬件加速(GPU 加速)</h2><p>浏览器在处理下面的 css 的时候，会使用 GPU 渲染</p>
<ul>
<li>transform（当 3D 变换的样式出现时会使用 GPU 加速）</li>
<li>opacity</li>
<li>filter</li>
<li>will-change</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">采用 transform: translateZ(<span class="number">0</span>)</span><br><span class="line">采用 transform: translate3d(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>)</span><br><span class="line">使用 CSS 的 will-change属性。 will-change 可以设置为opacity、transform、top、left、bottom、right。</span><br></pre></td></tr></table></figure>

<blockquote>
<p>注意！层爆炸，由于某些原因可能导致产生大量不在预期内的合成层，虽然有浏览器的层压缩机制，但是也有很多无法进行压缩的情况，这就可能出现层爆炸的现象（简单理解就是，很多不需要提升为合成层的元素因为某些不当操作成为了合成层）。解决层爆炸的问题，最佳方案是打破 overlap 的条件，也就是说让其他元素不要和合成层元素重叠。简单直接的方式：使用 3D 硬件加速提升动画性能时，最好给元素增加一个 z-index 属性，人为干扰合成的排序，可以有效减少创建不必要的合成层，提升渲染性能，移动端优化效果尤为明显。</p>
</blockquote>
<h1 id="三、Javascript部分"><a href="#三、Javascript部分" class="headerlink" title="三、Javascript部分"></a>三、Javascript部分</h1><h2 id="3-1-js数据类型有哪些"><a href="#3-1-js数据类型有哪些" class="headerlink" title="3.1 js数据类型有哪些"></a>3.1 js数据类型有哪些</h2><p>Number 、String、Boolean、Null、Undefined、Object、Symbol、BigInt</p>
<h2 id="3-2-怎么判断对象还是数组？"><a href="#3-2-怎么判断对象还是数组？" class="headerlink" title="3.2 怎么判断对象还是数组？"></a>3.2 怎么判断对象还是数组？</h2><p>   <strong>最少3种以上</strong></p>
<ul>
<li><strong>instanceof</strong></li>
<li><strong>对象的constructor属性</strong></li>
<li><strong>Object.prototype.toString.call(arr)</strong></li>
<li><strong>Array.isArray()</strong> </li>
</ul>
<h2 id="3-3-new关键字做了什么"><a href="#3-3-new关键字做了什么" class="headerlink" title="3.3 new关键字做了什么"></a>3.3 new关键字做了什么</h2><ul>
<li>创建一个简单空对象</li>
<li>原型的执行，确定对象o的原型链</li>
<li>绑定this对象为o，传入参数；执行Person构造函数，进行属性和方法的赋值操作</li>
<li>返回结果</li>
</ul>
<h2 id="3-4-Javascript事件流"><a href="#3-4-Javascript事件流" class="headerlink" title="3.4  Javascript事件流"></a>3.4  Javascript事件流</h2><p>DOM事件流是有两种的，一种是捕获型事件流，另外一种是冒泡型事件流，两者其实都很好理解，下面我们就来详细介绍一下，为了大家更好的理解，我们就先介绍下冒泡型事件流</p>
<ol>
<li>冒泡型事件流 **”冒泡”**：没错就是你心中想的，冒泡就是我们平时可以常见的，例如水中的气泡往上冒，这就是冒泡，所以冒泡型事件流，就是当你点击目标元素的时候，当前所触发的一些事件会向父元素中传递，这就是所谓的事件冒泡,如果大家还是有不理解的地方，可以直接看后面的代码</li>
<li>捕获型事件流 捕获型事件流正好是与冒泡型事件流相反的，当你点击目标元素的时候，在该目标元素上点击触发的事件，会从父元素向下传递</li>
<li>其实，DOM标准规定事件流包括三个阶段：事件捕获阶段、处于目标阶段和事件冒泡阶段。 事件捕获阶段：实际目标在捕获阶段不会接收事件。也就是在捕获阶段，事件从document到再到就停止了。 处于目标阶段：事件在上发生并处理。但是事件处理会被看成是冒泡阶段的一部分。 冒泡阶段：事件又传播回文档。</li>
</ol>
<h2 id="3-5-怎么阻止冒泡事件"><a href="#3-5-怎么阻止冒泡事件" class="headerlink" title="3.5 怎么阻止冒泡事件"></a>3.5 怎么阻止冒泡事件</h2><p>w3c:  event.stopPropagation()</p>
<p>IE:     window.event.cancelBubble = true</p>
<h2 id="3-6-怎么阻止默认事件"><a href="#3-6-怎么阻止默认事件" class="headerlink" title="3.6 怎么阻止默认事件"></a>3.6 怎么阻止默认事件</h2><p>event.preventDefault()</p>
<h2 id="3-7-什么是事件委托"><a href="#3-7-什么是事件委托" class="headerlink" title="3.7 什么是事件委托"></a>3.7 什么是事件委托</h2><p>用事件冒泡的原理，自己所触发的事件， 让他的父元素代替执行。</p>
<h2 id="3-8-什么是抖动-节流"><a href="#3-8-什么是抖动-节流" class="headerlink" title="3.8 什么是抖动 节流"></a>3.8 什么是抖动 节流</h2><p>参考:</p>
<p><a target="_blank" rel="noopener" href="https://blog.csdn.net/Welkin_qing/article/details/88126044">https://blog.csdn.net/Welkin_qing/article/details/88126044</a></p>
<ul>
<li><p>函数防抖</p>
<p><strong>规定函数至少间隔多久执行</strong></p>
</li>
<li><p>函数节流</p>
<p><strong>规定函数在某时间段内最多执行一次</strong></p>
</li>
</ul>
<p>函数防抖和函数节流的对比<br>不管是函数节流还是函数防抖，减少的都是事件处理程序的调用频率，而不是时间的调用频率</p>
<p>何时使用函数防抖，何时使用函数节流？<br>当我们只需要处理最后一次触发事件时，用函数防抖。（例如：窗口大小变化，并不需要计算中间变化的过程，只需要窗口大小改变完成后的值）<br>当事件触发过于频繁，我们需要限制事件处理程序的调用频率时，用函数节流</p>
<h2 id="3-9-什么是深浅拷贝怎么实现"><a href="#3-9-什么是深浅拷贝怎么实现" class="headerlink" title="3.9 什么是深浅拷贝怎么实现"></a>3.9 什么是深浅拷贝怎么实现</h2><p>浅拷贝只是拷贝一层, 更深层次对象级别的只拷贝引用. 不拷贝地址，两者属性值指向同一内存空间。简单来讲，就是改变其中一个对象，另一个对象也会跟着改变。</p>
<p>拷贝对象各个层级的属性。简单的讲，就是复制出来的每个对象都有属于自己的内存空间，不会互相干扰。</p>
<p>实现: 最少2种 – 深度拷贝</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 深拷贝：对对象内部进行深拷贝，支持 Array、Date、RegExp、DOM</span></span><br><span class="line"><span class="keyword">const</span> deepCopy = <span class="function">(<span class="params">sourceObj</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="comment">// 如果不是对象则退出（可停止递归）</span></span><br><span class="line">  <span class="keyword">if</span>(<span class="keyword">typeof</span> sourceObj !== <span class="string">&#x27;object&#x27;</span>) <span class="keyword">return</span>;</span><br><span class="line">  </span><br><span class="line">  <span class="comment">// 深拷贝初始值：对象/数组</span></span><br><span class="line">  <span class="keyword">let</span> newObj = (sourceObj <span class="keyword">instanceof</span> <span class="built_in">Array</span>) ? [] : &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 使用 for-in 循环对象属性（包括原型链上的属性）</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">let</span> key <span class="keyword">in</span> sourceObj) &#123; </span><br><span class="line">    <span class="comment">// 只访问对象自身属性</span></span><br><span class="line">    <span class="keyword">if</span> (sourceObj.hasOwnProperty(key)) &#123;</span><br><span class="line">      <span class="comment">// 当前属性还未存在于新对象中时</span></span><br><span class="line">      <span class="keyword">if</span>(!(key <span class="keyword">in</span> newObj))&#123;</span><br><span class="line">        <span class="keyword">if</span> (sourceObj[key] <span class="keyword">instanceof</span> <span class="built_in">Date</span>) &#123;</span><br><span class="line">          <span class="comment">// 判断日期类型</span></span><br><span class="line">          newObj[key] = <span class="keyword">new</span> <span class="built_in">Date</span>(sourceObj[key].getTime());</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (sourceObj[key] <span class="keyword">instanceof</span> <span class="built_in">RegExp</span>) &#123;</span><br><span class="line">          <span class="comment">// 判断正则类型</span></span><br><span class="line">          newObj[key] = <span class="keyword">new</span> <span class="built_in">RegExp</span>(sourceObj[key]);</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> ((<span class="keyword">typeof</span> sourceObj[key] === <span class="string">&#x27;object&#x27;</span>) &amp;&amp; sourceObj[key].nodeType === <span class="number">1</span> ) &#123;</span><br><span class="line">          <span class="comment">// 判断 DOM 元素节点</span></span><br><span class="line">          <span class="keyword">let</span> domEle = <span class="built_in">document</span>.getElementsByTagName(sourceObj[key].nodeName)[<span class="number">0</span>];</span><br><span class="line">          newObj[key] = domEle.cloneNode(<span class="literal">true</span>);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">          <span class="comment">// 当元素属于对象（排除 Date、RegExp、DOM）类型时递归拷贝</span></span><br><span class="line">          newObj[key] = (<span class="keyword">typeof</span> sourceObj[key] === <span class="string">&#x27;object&#x27;</span>) ? deepCopy(sourceObj[key]) : sourceObj[key];</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  </span><br><span class="line">  <span class="keyword">return</span> newObj;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// deepCopy 函数测试效果</span></span><br><span class="line"><span class="keyword">const</span> objA = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;jack&#x27;</span>,</span><br><span class="line">  <span class="attr">birthday</span>: <span class="keyword">new</span> <span class="built_in">Date</span>(),</span><br><span class="line">  <span class="attr">pattern</span>: <span class="regexp">/jack/g</span>,</span><br><span class="line">  body: <span class="built_in">document</span>.body,</span><br><span class="line">  <span class="attr">others</span>: [<span class="number">123</span>,<span class="string">&#x27;coding&#x27;</span>, <span class="keyword">new</span> <span class="built_in">Date</span>(), <span class="regexp">/abc/gim</span>,]</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> objB = deepCopy(objA);</span><br><span class="line"><span class="built_in">console</span>.log(objA === objB); <span class="comment">// false</span></span><br><span class="line"><span class="built_in">console</span>.log(objA.others === objB.others); <span class="comment">// false</span></span><br><span class="line"><span class="built_in">console</span>.log(objA, objB); <span class="comment">// 对象内容一样</span></span><br></pre></td></tr></table></figure>



<h2 id="3-20-call、bind和apply的区别"><a href="#3-20-call、bind和apply的区别" class="headerlink" title="3.20 call、bind和apply的区别"></a>3.20 call、bind和apply的区别</h2><ol>
<li><p> 都可以更改this指向</p>
</li>
<li><p> call，bind后面的第一个参数是指向的对象，第二个参数是往对象传的值</p>
</li>
<li><p> apply后面的第一个参数是指向的对象，第二个参数是数组，数组里面是往对象传的值（arguments  全部参数）</p>
</li>
<li><p> call和apply更改this指向会自动调用，bind需要手动调用</p>
</li>
</ol>
<h2 id="3-21-cookie，sessionStorage和localStorage的区别是什么"><a href="#3-21-cookie，sessionStorage和localStorage的区别是什么" class="headerlink" title="3.21 cookie，sessionStorage和localStorage的区别是什么"></a>3.21 cookie，sessionStorage和localStorage的区别是什么</h2><ol>
<li><p>都可以用来存储数据</p>
</li>
<li><p>cookie一条数据大小不能超过4KB ，最多不能存储超过20条，如果没有设置过期时间，那么在浏览器关闭后消失</p>
</li>
<li><p>sessionStorage是会话存储，一条大小不能超过5M，数量没有限制，关掉页面数据消失</p>
</li>
<li><p>localStorage本地存储，一条大小不超过5M，数量没有限制，除非主动删除，否则数据不会消失</p>
</li>
</ol>
<h2 id="3-22-什么是原型链"><a href="#3-22-什么是原型链" class="headerlink" title="3.22  什么是原型链"></a>3.22  什么是原型链</h2><p>当访问一个对象的某个属性时，会先在这个对象本身属性上查找，如果没有找到，则会去它的__proto__隐式原型上查找，即它的构造函数的prototype，如果还没有找到就会再在构造函数的prototype的__proto__中查找，这样一层一层向上查找就会形成一个链式结构，我们称为原型链<br><img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg-blog.csdnimg.cn%2F20200324172235599.png%3Fx-oss-process%3Dimage%2Fwatermark%2Ctype_ZmFuZ3poZW5naGVpdGk%2Cshadow_10%2Ctext_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjMzODU4NA%3D%3D%2Csize_16%2Ccolor_FFFFFF%2Ct_70&refer=http%3A%2F%2Fimg-blog.csdnimg.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1634980485&t=0701089532bb49fd02da93167363a8db" alt="img"></p>
<h2 id="3-23-什么是闭包？闭包的作用场景是什么？"><a href="#3-23-什么是闭包？闭包的作用场景是什么？" class="headerlink" title="3.23 什么是闭包？闭包的作用场景是什么？"></a>3.23 什么是闭包？闭包的作用场景是什么？</h2><p>闭包指的是一个函数可以访问另一个函数作用域中变量</p>
<p>各种专业文献上的”闭包”（closure）定义非常抽象，很难看懂。我的理解是，<strong>闭包就是能够读取其他函数内部变量的函数</strong>。</p>
<p>由于在Javascript语言中，只有函数内部的子函数才能读取局部变量，因此可以把**闭包简单理解成”定义在一个函数内部的函数”**。</p>
<p>所以，在本质上，<strong>闭包就是将函数内部和函数外部连接起来的一座桥梁。</strong></p>
<ul>
<li><p>采用函数引用方式的setTimeout调用</p>
</li>
<li><p>小范围代替全局变量</p>
</li>
<li><p>访问私有变量的特权方法</p>
</li>
<li><p>模块化</p>
<p>使用作用域链的形式说明闭包是什么？</p>
<p>当外层函数执行时，内层函数进行定义，此时内层函数生成作用域链，作用域链中包含外层函数的AO对象，导致AO无法释放，这就形成了闭包。</p>
</li>
</ul>
<p><strong>闭包缺点：</strong>会导致函数的变量一直保存在内存中，过多的闭包可能会导致内存泄漏</p>
<h2 id="3-24-同步异步的区别是什么"><a href="#3-24-同步异步的区别是什么" class="headerlink" title="3.24 同步异步的区别是什么"></a>3.24 同步异步的区别是什么</h2><p><em><strong>*同步：上一个任务没有执行完，下一个任务不能开启*</strong></em></p>
<p><em><strong>*异步：即便上一个任务没有执行完，下一个任务仍然可以开启*</strong></em></p>
<h2 id="3-25-Javascript中异步操作-及其js中EventLoop-事件循环"><a href="#3-25-Javascript中异步操作-及其js中EventLoop-事件循环" class="headerlink" title="3.25 Javascript中异步操作 及其js中EventLoop 事件循环"></a>3.25 Javascript中异步操作 及其js中EventLoop 事件循环</h2><p><strong>(1)</strong> <em><strong>*setTimeout 延时器*</strong></em></p>
<p><strong>(2)</strong> <em><strong>*setInterval 计时器*</strong></em></p>
<p><strong>(3)</strong> <em><strong>*数据请求*</strong></em></p>
<p>EventLoop ： 暂定</p>
<h2 id="3-26-es6有哪些新特性"><a href="#3-26-es6有哪些新特性" class="headerlink" title="3.26 es6有哪些新特性"></a>3.26 es6有哪些新特性</h2><p>​    1.let关键字，声明变量</p>
<p>​    2.const关键字，声明常量</p>
<p>​    3.模板字符串</p>
<p>​    4.箭头函数</p>
<p>​    5.对象和数组解构</p>
<p>​    6.Map、Set集合</p>
<p>​    7.Promise对象</p>
<p>​    8.引入class关键字</p>
<p>​    9.ES6模块化</p>
<h2 id="3-27-var-和let、Const的区别是什么"><a href="#3-27-var-和let、Const的区别是什么" class="headerlink" title="3.27 var 和let、Const的区别是什么"></a>3.27 var 和let、Const的区别是什么</h2><p>(1) let声明的变量只能先声明后赋值</p>
<p>(2) 只能使用let对同一个变量声明一次</p>
<p>(3) let声明的变量有块级作用域</p>
<h2 id="3-28-数组的常用方法有哪些？"><a href="#3-28-数组的常用方法有哪些？" class="headerlink" title="3.28 数组的常用方法有哪些？"></a>3.28 数组的常用方法有哪些？</h2><p>pop、push、cancat、shift、unshift、join、filter、map、some、everything、reduce、find、splice</p>
<h2 id="3-29-字符串常用的方法有哪些？"><a href="#3-29-字符串常用的方法有哪些？" class="headerlink" title="3.29 字符串常用的方法有哪些？"></a>3.29 字符串常用的方法有哪些？</h2><p>substr、slice、concat、</p>
<h2 id="3-30-数组怎么进行去重-（3种以上方法）"><a href="#3-30-数组怎么进行去重-（3种以上方法）" class="headerlink" title="3.30 数组怎么进行去重 （3种以上方法）"></a>3.30 数组怎么进行去重 （3种以上方法）</h2><ul>
<li>利用ES6 Set去重（ES6中最常用）</li>
<li>利用for嵌套for，然后splice去重（ES5中最常用）</li>
<li>利用indexOf去重</li>
<li>利用includes</li>
<li>利用filter</li>
</ul>
<h2 id="3-31-数组扁平化"><a href="#3-31-数组扁平化" class="headerlink" title="3.31 数组扁平化"></a>3.31 数组扁平化</h2><ul>
<li><h4 id="ES5-递归"><a href="#ES5-递归" class="headerlink" title="ES5+递归"></a>ES5+递归</h4></li>
<li><h4 id="ES6-reduce-递归"><a href="#ES6-reduce-递归" class="headerlink" title="ES6+reduce+递归"></a>ES6+reduce+递归</h4></li>
<li><h3 id="ES6-Flat函数"><a href="#ES6-Flat函数" class="headerlink" title="ES6 Flat函数"></a>ES6 Flat函数</h3></li>
</ul>
<h2 id="3-32-什么是纯函数"><a href="#3-32-什么是纯函数" class="headerlink" title="3.32 什么是纯函数"></a>3.32 什么是纯函数</h2><pre><code>纯函数的概念：一个函数的返回结果只依赖其参数，并且执行过程中没有副作用。
</code></pre>
<h2 id="3-33-什么是高阶函数"><a href="#3-33-什么是高阶函数" class="headerlink" title="3.33 什么是高阶函数"></a>3.33 什么是高阶函数</h2><p>   一个函数作为另外一个函数的参数或者一个函数的返回值为另外一个函数这种函数就称之为高阶函数。</p>
<h2 id="3-34-函数柯里化及其用途"><a href="#3-34-函数柯里化及其用途" class="headerlink" title="3.34 函数柯里化及其用途"></a>3.34 函数柯里化及其用途</h2><p>柯里化，英语：Currying，是把接受多个参数的函数变换成接受一个单一参数（最初函数的第一个参数）的函数，并且返回接受余下的参数而且返回结果的新函数的技术。<br>应用:<br>  参考地址: <a target="_blank" rel="noopener" href="https://blog.csdn.net/qq_18404993/article/details/108836643">https://blog.csdn.net/qq_18404993/article/details/108836643</a><br> -参数复用</p>
<ul>
<li>兼容性检测：提前确认/提前返回</li>
<li>延迟执行 </li>
</ul>
<h2 id="3-35-怎么解决异步回调地狱问题"><a href="#3-35-怎么解决异步回调地狱问题" class="headerlink" title="3.35 怎么解决异步回调地狱问题?"></a>3.35 怎么解决异步回调地狱问题?</h2><p>Promise、generator、async await</p>
<h2 id="3-36-说一下Promise的使用？"><a href="#3-36-说一下Promise的使用？" class="headerlink" title="3.36 说一下Promise的使用？"></a>3.36 说一下Promise的使用？</h2><p>Promise是异步编程的一种解决方案，在ES6中Promise被列为了正式规范，统一了用法，原生提供了Promise对象。<strong>Promise承诺：默认情况下是等待状态pending，如果有一天状态转变为成功就成功了，如果状态变成失败就失败了。状态一旦改变了就不能再改变了。</strong></p>
<p>三种状态： pending，Resolved， Rejected</p>
<ul>
<li>then 方法</li>
<li>catch的用法</li>
<li>finally方法</li>
<li>all的用法</li>
<li>race的用法</li>
<li>Promise的静态方法</li>
</ul>
<h2 id="3-37-怎么将伪数组转换成真正的数组？"><a href="#3-37-怎么将伪数组转换成真正的数组？" class="headerlink" title="3.37 怎么将伪数组转换成真正的数组？"></a>3.37 怎么将伪数组转换成真正的数组？</h2><ul>
<li><p>```javascript<br>Array.prototype.slice.call(arguments,0) // 使用slice方法实现</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">- ```javascript</span><br><span class="line">  Array.from(arguments) // 使用ES6中的函数</span><br></pre></td></tr></table></figure></li>
<li><p>```javascript<br>[…arguments]</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">## 3.38 斐波那契数列怎么实现？</span><br><span class="line"></span><br><span class="line">- 第一种实现：普通递归</span><br><span class="line"></span><br><span class="line">  ```javascript</span><br><span class="line">  function fibonacci(n) &#123;</span><br><span class="line">      if (n == 1 || n == 2) &#123;</span><br><span class="line">          return 1</span><br><span class="line">      &#125;;</span><br><span class="line">      return fibonacci(n - 2) + fibonacci(n - 1);</span><br><span class="line">  &#125;</span><br><span class="line">  fibonacci(30)</span><br></pre></td></tr></table></figure></li>
<li><p>第二种实现: 改进递归-把前两位数字做成参数避免重复计算</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fibonacci</span>(<span class="params">n</span>) </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">fib</span>(<span class="params">n, v1, v2</span>) </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (n == <span class="number">1</span>)</span><br><span class="line">            <span class="keyword">return</span> v1;</span><br><span class="line">        <span class="keyword">if</span> (n == <span class="number">2</span>)</span><br><span class="line">            <span class="keyword">return</span> v2;</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">            <span class="keyword">return</span> fib(n - <span class="number">1</span>, v2, v1 + v2)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> fib(n, <span class="number">1</span>, <span class="number">1</span>)</span><br><span class="line">&#125;</span><br><span class="line">fibonacci(<span class="number">30</span>)</span><br></pre></td></tr></table></figure></li>
<li><p>第三种实现：改进递归-利用闭包特性把运算结果存储在数组里，避免重复计算</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> fibonacci = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> memo = [<span class="number">0</span>, <span class="number">1</span>];</span><br><span class="line">    <span class="keyword">let</span> fib = <span class="function"><span class="keyword">function</span> (<span class="params">n</span>) </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (memo[n] == <span class="literal">undefined</span>) &#123;</span><br><span class="line">            memo[n] = fib(n - <span class="number">2</span>) + fib(n - <span class="number">1</span>)</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> memo[n]</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> fib;</span><br><span class="line">&#125;()</span><br><span class="line">fibonacci(<span class="number">30</span>)</span><br></pre></td></tr></table></figure></li>
<li><p>第四种实现: 改进递归-摘出存储计算结果的功能函数</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> memoizer = <span class="function"><span class="keyword">function</span> (<span class="params">func</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> memo = [];</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params">n</span>) </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (memo[n] == <span class="literal">undefined</span>) &#123;</span><br><span class="line">            memo[n] = func(n)</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> memo[n]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">var</span> fibonacci=memoizer(<span class="function"><span class="keyword">function</span>(<span class="params">n</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (n == <span class="number">1</span> || n == <span class="number">2</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span></span><br><span class="line">    &#125;;</span><br><span class="line">    <span class="keyword">return</span> fibonacci(n - <span class="number">2</span>) + fibonacci(n - <span class="number">1</span>);</span><br><span class="line">&#125;)</span><br><span class="line">fibonacci(<span class="number">30</span>)</span><br></pre></td></tr></table></figure></li>
<li><p>第五种: 普通for循环</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fibonacci</span>(<span class="params">n</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> n1 = <span class="number">1</span>, n2 = <span class="number">1</span>, sum;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">2</span>; i &lt; n; i++) &#123;</span><br><span class="line">        sum = n1 + n2</span><br><span class="line">        n1 = n2</span><br><span class="line">        n2 = sum</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> sum</span><br><span class="line">&#125;</span><br><span class="line">fibonacci(<span class="number">30</span>)</span><br></pre></td></tr></table></figure></li>
<li><p>第六种：for循环+解构赋值</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> fibonacci = <span class="function"><span class="keyword">function</span> (<span class="params">n</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> n1 = <span class="number">1</span>; n2 = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">2</span>; i &lt; n; i++) &#123;</span><br><span class="line">        [n1, n2] = [n2, n1 + n2]</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> n2</span><br><span class="line">&#125;</span><br><span class="line">fibonacci(<span class="number">30</span>)</span><br></pre></td></tr></table></figure>

<p>这六种方法需要会 第六种 和 第三种。其他需要了解</p>
</li>
</ul>
<h2 id="3-39-冒泡算法"><a href="#3-39-冒泡算法" class="headerlink" title="3.39 冒泡算法"></a>3.39 冒泡算法</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//从小到大</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">BubbleSort</span>(<span class="params">arr</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> i,j,temp;</span><br><span class="line">    <span class="keyword">for</span>(i=<span class="number">0</span>;i&lt;arr.length-<span class="number">1</span>;i++)&#123;</span><br><span class="line">        <span class="keyword">for</span>(j=i+<span class="number">1</span>;j&lt;arr.length;j++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(arr[i]&gt;arr[j])&#123;</span><br><span class="line">                temp=arr[j];</span><br><span class="line">                arr[j]=arr[i];</span><br><span class="line">                arr[i]=temp;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> arr;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> arr=[<span class="number">10</span>,<span class="number">7</span>,<span class="number">9</span>,<span class="number">11</span>,<span class="number">22</span>,<span class="number">33</span>,<span class="number">4</span>,<span class="number">2</span>,<span class="number">0</span>,<span class="number">1000</span>];</span><br><span class="line">BubbleSort(arr);  <span class="number">17</span> <span class="built_in">console</span>.log(arr); <span class="comment">//[0, 2, 4, 7, 9, 10, 11, 22, 33, 1000]</span></span><br></pre></td></tr></table></figure>

<h2 id="3-40-快排算法"><a href="#3-40-快排算法" class="headerlink" title="3.40 快排算法"></a>3.40 快排算法</h2><p>参考地址： <a target="_blank" rel="noopener" href="https://www.cnblogs.com/hjx-blog/articles/9183453.html">https://www.cnblogs.com/hjx-blog/articles/9183453.html</a></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> quickSort_New = <span class="function"><span class="keyword">function</span>(<span class="params">ary, left, right</span>) </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(left &gt;= right) &#123;</span><br><span class="line">            <span class="keyword">return</span> ary;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">var</span> i = left,</span><br><span class="line">             j = right;</span><br><span class="line">             base = ary[left];</span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span> (i &lt; j) &#123;</span><br><span class="line">            <span class="comment">// 从右边起，寻找比基数小的数</span></span><br><span class="line">            <span class="keyword">while</span> (i&lt;j &amp;&amp; ary[j] &gt;= base) &#123;</span><br><span class="line">                j--;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 从左边起，寻找比基数大的数</span></span><br><span class="line">            <span class="keyword">while</span> (i&lt;j &amp;&amp; ary[i] &lt;= base) &#123;</span><br><span class="line">                i++</span><br><span class="line">            &#125; </span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (i&lt;j) &#123;</span><br><span class="line">                <span class="keyword">var</span> temp = ary[i];</span><br><span class="line">                ary[i] = ary[j];</span><br><span class="line">                ary[j] = temp;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        ary[left] = ary[i];</span><br><span class="line">        ary[i] = base;</span><br><span class="line"></span><br><span class="line">        quickSort_New(ary, left, i-<span class="number">1</span>);</span><br><span class="line">        quickSort_New(ary, i+<span class="number">1</span>, right);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> ary;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h2 id="3-41-面向对象继承方式（ES5）"><a href="#3-41-面向对象继承方式（ES5）" class="headerlink" title="3.41 面向对象继承方式（ES5）"></a>3.41 面向对象继承方式（ES5）</h2><ul>
<li><p>原型链的方式来实现继承</p>
</li>
<li><p>借用构造函数</p>
</li>
<li><p>组合继承</p>
</li>
<li><p>寄生式继承</p>
</li>
<li><p>寄生式组合继承</p>
</li>
</ul>
<h2 id="3-42-EventLoop事件循环"><a href="#3-42-EventLoop事件循环" class="headerlink" title="3.42 EventLoop事件循环"></a>3.42 EventLoop事件循环</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">JS`是单线程的，为了防止一个函数执行时间过长阻塞后面的代码，所以会先将同步代码压入执行栈中，依次执行，将异步代码推入异步队列，异步队列又分为宏任务队列和微任务队列，因为宏任务队列的执行时间较长，所以微任务队列要优先于宏任务队列。微任务队列的代表就是，`Promise.then`，`MutationObserver`，宏任务的话就是`setImmediate setTimeout setInterval</span><br></pre></td></tr></table></figure>

<h2 id="3-43-介绍一下垃圾回收机制"><a href="#3-43-介绍一下垃圾回收机制" class="headerlink" title="3.43 介绍一下垃圾回收机制"></a>3.43 介绍一下垃圾回收机制</h2><p>垃圾回收机制大体上分为两种检测手段，引用计数与标记清除。</p>
<p>从2012年起，所有现代浏览器都使用了标记清除垃圾回收算法，但老版本的IE6除外。</p>
<p>如何避免内存泄漏：</p>
<p><strong>1.尽量减少全局变量</strong></p>
<p><strong>2.移除被遗忘的定时器或回调函数</strong></p>
<p><strong>3.及时释放闭包中的变量</strong></p>
<p><strong>4.DOM的引用时 不再使用DOM及时清除</strong></p>
<h2 id="3-43-Proxy的作用-有哪些方法？"><a href="#3-43-Proxy的作用-有哪些方法？" class="headerlink" title="3.43 Proxy的作用?有哪些方法？"></a>3.43 Proxy的作用?有哪些方法？</h2><p>Proxy 用于修改某些操作的默认行为，等同于在语言层面做出修改，所以属于一种“元编程”（meta programming），即对编程语言进行编程。Proxy 可以理解成，在目标对象之前架设一层“拦截”，外界对该对象的访问，都必须先通过这层拦截，因此提供了一种机制，可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理，用在这里表示由它来“代理”某些操作，可以译为“代理器”。</p>
<p>方法只需记住关键的几个即可：</p>
<ul>
<li>**get(target, propKey, receiver)**：拦截对象属性的读取，比如<code>proxy.foo</code>和<code>proxy[&#39;foo&#39;]</code>。 // 记住</li>
<li>**set(target, propKey, value, receiver)**：拦截对象属性的设置，比如<code>proxy.foo = v</code>或<code>proxy[&#39;foo&#39;] = v</code>，返回一个布尔值。// 记住</li>
<li>**has(target, propKey)**：拦截<code>propKey in proxy</code>的操作，返回一个布尔值。</li>
<li>**deleteProperty(target, propKey)**：拦截<code>delete proxy[propKey]</code>的操作，返回一个布尔值。 // 记住</li>
<li>**ownKeys(target)**：拦截<code>Object.getOwnPropertyNames(proxy)</code>、<code>Object.getOwnPropertySymbols(proxy)</code>、<code>Object.keys(proxy)</code>、<code>for...in</code>循环，返回一个数组。该方法返回目标对象所有自身的属性的属性名，而<code>Object.keys()</code>的返回结果仅包括目标对象自身的可遍历属性。</li>
<li>**getOwnPropertyDescriptor(target, propKey)**：拦截<code>Object.getOwnPropertyDescriptor(proxy, propKey)</code>，返回属性的描述对象。  // 记住</li>
<li>**defineProperty(target, propKey, propDesc)**：拦截<code>Object.defineProperty(proxy, propKey, propDesc）</code>、<code>Object.defineProperties(proxy, propDescs)</code>，返回一个布尔值。 // 记住</li>
<li>**preventExtensions(target)**：拦截<code>Object.preventExtensions(proxy)</code>，返回一个布尔值。</li>
<li>**getPrototypeOf(target)**：拦截<code>Object.getPrototypeOf(proxy)</code>，返回一个对象。</li>
<li>**isExtensible(target)**：拦截<code>Object.isExtensible(proxy)</code>，返回一个布尔值。</li>
<li>**setPrototypeOf(target, proto)**：拦截<code>Object.setPrototypeOf(proxy, proto)</code>，返回一个布尔值。如果目标对象是函数，那么还有两种额外操作可以拦截。</li>
<li>**apply(target, object, args)**：拦截 Proxy 实例作为函数调用的操作，比如<code>proxy(...args)</code>、<code>proxy.call(object, ...args)</code>、<code>proxy.apply(...)</code>。 // 记住</li>
<li>**construct(target, args)**：拦截 Proxy 实例作为构造函数调用的操作，比如<code>new proxy(...args)</code>。</li>
</ul>
<h2 id="3-44-前端优化之渲染百万条数据不卡顿"><a href="#3-44-前端优化之渲染百万条数据不卡顿" class="headerlink" title="3.44 前端优化之渲染百万条数据不卡顿"></a>3.44 前端优化之渲染百万条数据不卡顿</h2><p>参考网址: <a target="_blank" rel="noopener" href="https://juejin.cn/post/7011040313418448926#heading-7">https://juejin.cn/post/7011040313418448926#heading-7</a></p>
<p>Document.createDocumentFragment()： 用来创建虚拟DOM</p>
<p>window.requestAnimationFrame：告诉浏览器——你希望执行一个动画，并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数，该回调函数会在浏览器下一次重绘之前执行。</p>
<p><code>requestAnimationFrame</code> 会把每一帧中的所有<code>DOM</code>操作集中起来，在一次重绘或回流中就完成，并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率，一般来说，这个频率为每秒60帧。</p>
<p>在隐藏或不可见的元素中，<code>requestAnimationFrame</code>将不会进行重绘或回流，这当然就意味着更少的的<code>cpu</code>，<code>gpu</code>和内存使用量。</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="meta-keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">http-equiv</span>=<span class="string">&quot;X-UA-Compatible&quot;</span> <span class="attr">content</span>=<span class="string">&quot;IE=edge&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>Document<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">ul</span>&gt;</span><span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="javascript"></span></span><br><span class="line"><span class="javascript">      <span class="comment">// createDocumentFragment</span></span></span><br><span class="line"><span class="javascript">      <span class="comment">// requestAnimationFrame</span></span></span><br><span class="line"><span class="javascript"></span></span><br><span class="line"><span class="javascript">      <span class="comment">// 百万条数据</span></span></span><br><span class="line"><span class="javascript">      <span class="keyword">let</span> total = <span class="number">1000000</span>;</span></span><br><span class="line"><span class="javascript">      <span class="comment">// 单次插入 可自定义</span></span></span><br><span class="line"><span class="javascript">      <span class="keyword">let</span> once = <span class="number">20</span>;</span></span><br><span class="line"><span class="javascript">      <span class="comment">// 需要插入的次数 向上取整</span></span></span><br><span class="line"><span class="javascript">      <span class="keyword">let</span> loopCount = <span class="built_in">Math</span>.ceil(total / once);</span></span><br><span class="line"><span class="javascript">      <span class="comment">// 当前渲染次数</span></span></span><br><span class="line"><span class="javascript">      <span class="keyword">let</span> countRender = <span class="number">0</span>;</span></span><br><span class="line"><span class="javascript"></span></span><br><span class="line"><span class="javascript">      <span class="function"><span class="keyword">function</span> <span class="title">render</span>(<span class="params"></span>) </span>&#123;</span></span><br><span class="line"><span class="javascript">        <span class="comment">// 需要插入的目标对象</span></span></span><br><span class="line"><span class="javascript">        <span class="keyword">const</span> targetElement = <span class="built_in">document</span>.querySelector(<span class="string">&quot;ul&quot;</span>);</span></span><br><span class="line"><span class="javascript">        <span class="comment">// 文档因为存在片段于内存中，并不在DOM树中，将所以子元素插入到文档片段时不会引起页面回流（对元素位置和几何上的计算）。因此，使用文档片段通常会带来更好的性能。</span></span></span><br><span class="line"><span class="javascript">        <span class="comment">// 创建一个虚拟Dom节点 插入真实文档之前不会触发dom渲染、回流等操作</span></span></span><br><span class="line"><span class="javascript">        <span class="comment">// 因此能够很大程度减少dom操作所带来的的性能损耗</span></span></span><br><span class="line"><span class="javascript">        <span class="keyword">const</span> fragment = <span class="built_in">document</span>.createDocumentFragment();</span></span><br><span class="line"><span class="javascript"></span></span><br><span class="line"><span class="javascript">        <span class="comment">// 对虚拟节点插入dom节点，也不会触发真是dom操作，同上</span></span></span><br><span class="line"><span class="javascript">        <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; <span class="number">20</span>; i++) &#123;</span></span><br><span class="line"><span class="javascript">          <span class="comment">// 搞个节点</span></span></span><br><span class="line"><span class="javascript">          <span class="keyword">const</span> li = <span class="built_in">document</span>.createElement(<span class="string">&quot;li&quot;</span>);</span></span><br><span class="line"><span class="javascript">          <span class="comment">// 给li搞点内容</span></span></span><br><span class="line"><span class="javascript">          li.innerHTML = <span class="built_in">Math</span>.random();</span></span><br><span class="line"><span class="javascript">          <span class="comment">// 插入到虚拟节点</span></span></span><br><span class="line"><span class="javascript">          fragment.appendChild(li);</span></span><br><span class="line"><span class="javascript">        &#125;</span></span><br><span class="line"><span class="javascript">        <span class="comment">// 插入到真实节点的时候，只会把虚拟fragment下的子孙节点插入</span></span></span><br><span class="line"><span class="javascript">        targetElement.appendChild(fragment);</span></span><br><span class="line"><span class="javascript">        <span class="comment">// 渲染次数加1，控制递归的次数</span></span></span><br><span class="line"><span class="javascript">        countRender++;</span></span><br><span class="line"><span class="javascript">        <span class="comment">// // 递归调用</span></span></span><br><span class="line"><span class="javascript">        <span class="keyword">if</span> (countRender &lt; loopCount) &#123;</span></span><br><span class="line"><span class="javascript">          <span class="comment">// window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画，并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。</span></span></span><br><span class="line"><span class="javascript">          <span class="comment">// 回调函数执行次数通常是每秒60次，但在大多数遵循W3C建议的浏览器中，回调函数执行次数通常与浏览器屏幕刷新次数相匹配。</span></span></span><br><span class="line"><span class="javascript">          <span class="comment">// 能够把每次dom的操作汇总在下一次重绘之前更新动画帧</span></span></span><br><span class="line"><span class="javascript">          <span class="comment">// 因此在浏览器单线程的机制下，能够无卡顿的加载，百万级列表</span></span></span><br><span class="line"><span class="javascript">          <span class="built_in">window</span>.requestAnimationFrame(render);</span></span><br><span class="line"><span class="javascript">        &#125;</span></span><br><span class="line"><span class="javascript">      &#125;</span></span><br><span class="line"><span class="javascript"></span></span><br><span class="line"><span class="javascript">      <span class="comment">// 执行渲染</span></span></span><br><span class="line"><span class="javascript">      render();</span></span><br><span class="line"><span class="javascript">    </span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>还有一种方案可以提高性能：</p>
<p>如果对于大量的数据，只应用于展示的话，可以使用**<code>Object.freeze()</code>** 方法可以<strong>冻结</strong>一个对象。一个被冻结的对象再也不能被修改；（这样可以让Vue不对对象增加getter和setter操作，从而提高性能）</p>
<h2 id="3-45-手写实现Promise"><a href="#3-45-手写实现Promise" class="headerlink" title="3.45 手写实现Promise"></a>3.45 手写实现Promise</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> PENDING = <span class="string">&#x27;PENDING&#x27;</span>;</span><br><span class="line"><span class="keyword">const</span> FULFILLED = <span class="string">&#x27;FULFILLED&#x27;</span>;</span><br><span class="line"><span class="keyword">const</span> REJECTED = <span class="string">&#x27;REJECTED&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> resolvePromise = <span class="function">(<span class="params">promise2, x, resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="comment">// 自己等待自己完成是错误的实现，用一个类型错误，结束掉 promise  Promise/A+ 2.3.1</span></span><br><span class="line">  <span class="keyword">if</span> (promise2 === x) &#123; </span><br><span class="line">    <span class="keyword">return</span> reject(<span class="keyword">new</span> <span class="built_in">TypeError</span>(<span class="string">&#x27;Chaining cycle detected for promise #&lt;Promise&gt;&#x27;</span>))</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// Promise/A+ 2.3.3.3.3 只能调用一次</span></span><br><span class="line">  <span class="keyword">let</span> called;</span><br><span class="line">  <span class="comment">// 后续的条件要严格判断 保证代码能和别的库一起使用</span></span><br><span class="line">  <span class="keyword">if</span> ((<span class="keyword">typeof</span> x === <span class="string">&#x27;object&#x27;</span> &amp;&amp; x != <span class="literal">null</span>) || <span class="keyword">typeof</span> x === <span class="string">&#x27;function&#x27;</span>) &#123; </span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      <span class="comment">// 为了判断 resolve 过的就不用再 reject 了（比如 reject 和 resolve 同时调用的时候）  Promise/A+ 2.3.3.1</span></span><br><span class="line">      <span class="keyword">let</span> then = x.then;</span><br><span class="line">      <span class="keyword">if</span> (<span class="keyword">typeof</span> then === <span class="string">&#x27;function&#x27;</span>) &#123; </span><br><span class="line">        <span class="comment">// 不要写成 x.then，直接 then.call 就可以了 因为 x.then 会再次取值，Object.defineProperty  Promise/A+ 2.3.3.3</span></span><br><span class="line">        then.call(x, <span class="function"><span class="params">y</span> =&gt;</span> &#123; <span class="comment">// 根据 promise 的状态决定是成功还是失败</span></span><br><span class="line">          <span class="keyword">if</span> (called) <span class="keyword">return</span>;</span><br><span class="line">          called = <span class="literal">true</span>;</span><br><span class="line">          <span class="comment">// 递归解析的过程（因为可能 promise 中还有 promise） Promise/A+ 2.3.3.3.1</span></span><br><span class="line">          resolvePromise(promise2, y, resolve, reject); </span><br><span class="line">        &#125;, <span class="function"><span class="params">r</span> =&gt;</span> &#123;</span><br><span class="line">          <span class="comment">// 只要失败就失败 Promise/A+ 2.3.3.3.2</span></span><br><span class="line">          <span class="keyword">if</span> (called) <span class="keyword">return</span>;</span><br><span class="line">          called = <span class="literal">true</span>;</span><br><span class="line">          reject(r);</span><br><span class="line">        &#125;);</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="comment">// 如果 x.then 是个普通值就直接返回 resolve 作为结果  Promise/A+ 2.3.3.4</span></span><br><span class="line">        resolve(x);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">      <span class="comment">// Promise/A+ 2.3.3.2</span></span><br><span class="line">      <span class="keyword">if</span> (called) <span class="keyword">return</span>;</span><br><span class="line">      called = <span class="literal">true</span>;</span><br><span class="line">      reject(e)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="comment">// 如果 x 是个普通值就直接返回 resolve 作为结果  Promise/A+ 2.3.4  </span></span><br><span class="line">    resolve(x)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Promise</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="title">constructor</span>(<span class="params">executor</span>)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.status = PENDING;</span><br><span class="line">    <span class="built_in">this</span>.value = <span class="literal">undefined</span>;</span><br><span class="line">    <span class="built_in">this</span>.reason = <span class="literal">undefined</span>;</span><br><span class="line">    <span class="built_in">this</span>.onResolvedCallbacks = [];</span><br><span class="line">    <span class="built_in">this</span>.onRejectedCallbacks= [];</span><br><span class="line"></span><br><span class="line">    <span class="keyword">let</span> resolve = <span class="function">(<span class="params">value</span>) =&gt;</span> &#123;</span><br><span class="line">      <span class="keyword">if</span>(<span class="built_in">this</span>.status ===  PENDING) &#123;</span><br><span class="line">        <span class="built_in">this</span>.status = FULFILLED;</span><br><span class="line">        <span class="built_in">this</span>.value = value;</span><br><span class="line">        <span class="built_in">this</span>.onResolvedCallbacks.forEach(<span class="function"><span class="params">fn</span>=&gt;</span>fn());</span><br><span class="line">      &#125;</span><br><span class="line">    &#125; </span><br><span class="line"></span><br><span class="line">    <span class="keyword">let</span> reject = <span class="function">(<span class="params">reason</span>) =&gt;</span> &#123;</span><br><span class="line">      <span class="keyword">if</span>(<span class="built_in">this</span>.status ===  PENDING) &#123;</span><br><span class="line">        <span class="built_in">this</span>.status = REJECTED;</span><br><span class="line">        <span class="built_in">this</span>.reason = reason;</span><br><span class="line">        <span class="built_in">this</span>.onRejectedCallbacks.forEach(<span class="function"><span class="params">fn</span>=&gt;</span>fn());</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      executor(resolve,reject)</span><br><span class="line">    &#125; <span class="keyword">catch</span> (error) &#123;</span><br><span class="line">      reject(error)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="title">then</span>(<span class="params">onFulfilled, onRejected</span>)</span> &#123;</span><br><span class="line">    <span class="comment">//解决 onFufilled，onRejected 没有传值的问题</span></span><br><span class="line">    <span class="comment">//Promise/A+ 2.2.1 / Promise/A+ 2.2.5 / Promise/A+ 2.2.7.3 / Promise/A+ 2.2.7.4</span></span><br><span class="line">    onFulfilled = <span class="keyword">typeof</span> onFulfilled === <span class="string">&#x27;function&#x27;</span> ? onFulfilled : <span class="function"><span class="params">v</span> =&gt;</span> v;</span><br><span class="line">    <span class="comment">//因为错误的值要让后面访问到，所以这里也要跑出个错误，不然会在之后 then 的 resolve 中捕获</span></span><br><span class="line">    onRejected = <span class="keyword">typeof</span> onRejected === <span class="string">&#x27;function&#x27;</span> ? onRejected : <span class="function"><span class="params">err</span> =&gt;</span> &#123; <span class="keyword">throw</span> err &#125;;</span><br><span class="line">    <span class="comment">// 每次调用 then 都返回一个新的 promise  Promise/A+ 2.2.7</span></span><br><span class="line">    <span class="keyword">let</span> promise2 = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">      <span class="keyword">if</span> (<span class="built_in">this</span>.status === FULFILLED) &#123;</span><br><span class="line">        <span class="comment">//Promise/A+ 2.2.2</span></span><br><span class="line">        <span class="comment">//Promise/A+ 2.2.4 --- setTimeout</span></span><br><span class="line">        <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">          <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="comment">//Promise/A+ 2.2.7.1</span></span><br><span class="line">            <span class="keyword">let</span> x = onFulfilled(<span class="built_in">this</span>.value);</span><br><span class="line">            <span class="comment">// x可能是一个proimise</span></span><br><span class="line">            resolvePromise(promise2, x, resolve, reject);</span><br><span class="line">          &#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">            <span class="comment">//Promise/A+ 2.2.7.2</span></span><br><span class="line">            reject(e)</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;, <span class="number">0</span>);</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">if</span> (<span class="built_in">this</span>.status === REJECTED) &#123;</span><br><span class="line">        <span class="comment">//Promise/A+ 2.2.3</span></span><br><span class="line">        <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">          <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">let</span> x = onRejected(<span class="built_in">this</span>.reason);</span><br><span class="line">            resolvePromise(promise2, x, resolve, reject);</span><br><span class="line">          &#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">            reject(e)</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;, <span class="number">0</span>);</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">if</span> (<span class="built_in">this</span>.status === PENDING) &#123;</span><br><span class="line">        <span class="built_in">this</span>.onResolvedCallbacks.push(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">          <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">              <span class="keyword">let</span> x = onFulfilled(<span class="built_in">this</span>.value);</span><br><span class="line">              resolvePromise(promise2, x, resolve, reject);</span><br><span class="line">            &#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">              reject(e)</span><br><span class="line">            &#125;</span><br><span class="line">          &#125;, <span class="number">0</span>);</span><br><span class="line">        &#125;);</span><br><span class="line"></span><br><span class="line">        <span class="built_in">this</span>.onRejectedCallbacks.push(<span class="function">()=&gt;</span> &#123;</span><br><span class="line">          <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">              <span class="keyword">let</span> x = onRejected(<span class="built_in">this</span>.reason);</span><br><span class="line">              resolvePromise(promise2, x, resolve, reject)</span><br><span class="line">            &#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">              reject(e)</span><br><span class="line">            &#125;</span><br><span class="line">          &#125;, <span class="number">0</span>);</span><br><span class="line">        &#125;);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">  </span><br><span class="line">    <span class="keyword">return</span> promise2;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">作者：齐小神</span><br><span class="line">链接：https:<span class="comment">//juejin.cn/post/6850037281206566919</span></span><br><span class="line">来源：稀土掘金</span><br><span class="line">著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。</span><br></pre></td></tr></table></figure>

<h2 id="3-46-手写bind函数"><a href="#3-46-手写bind函数" class="headerlink" title="3.46 手写bind函数"></a>3.46 手写bind函数</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//bind实现要复杂一点  因为他考虑的情况比较多 还要涉及到参数合并(类似函数柯里化)</span></span><br><span class="line"><span class="built_in">Function</span>.prototype.myBind = <span class="function"><span class="keyword">function</span> (<span class="params">context, ...args</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (!context || context === <span class="literal">null</span>) &#123;</span><br><span class="line">    context = <span class="built_in">window</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 创造唯一的key值  作为我们构造的context内部方法名</span></span><br><span class="line">  <span class="keyword">let</span> fn = <span class="built_in">Symbol</span>();</span><br><span class="line">  context[fn] = <span class="built_in">this</span>;</span><br><span class="line">  <span class="keyword">let</span> _this = <span class="built_in">this</span>;</span><br><span class="line">  <span class="comment">//  bind情况要复杂一点</span></span><br><span class="line">  <span class="keyword">const</span> result = <span class="function"><span class="keyword">function</span> (<span class="params">...innerArgs</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 第一种情况 :若是将 bind 绑定之后的函数当作构造函数，通过 new 操作符使用，则不绑定传入的 this，而是将 this 指向实例化出来的对象</span></span><br><span class="line">    <span class="comment">// 此时由于new操作符作用  this指向result实例对象  而result又继承自传入的_this 根据原型链知识可得出以下结论</span></span><br><span class="line">    <span class="comment">// this.__proto__ === result.prototype   //this instanceof result =&gt;true</span></span><br><span class="line">    <span class="comment">// this.__proto__.__proto__ === result.prototype.__proto__ === _this.prototype; //this instanceof _this =&gt;true</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="built_in">this</span> <span class="keyword">instanceof</span> _this === <span class="literal">true</span>) &#123;</span><br><span class="line">      <span class="comment">// 此时this指向指向result的实例  这时候不需要改变this指向</span></span><br><span class="line">      <span class="built_in">this</span>[fn] = _this;</span><br><span class="line">      <span class="built_in">this</span>[fn](...[...args, ...innerArgs]); <span class="comment">//这里使用es6的方法让bind支持参数合并</span></span><br><span class="line">      <span class="keyword">delete</span> <span class="built_in">this</span>[fn];</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="comment">// 如果只是作为普通函数调用  那就很简单了 直接改变this指向为传入的context</span></span><br><span class="line">      context[fn](...[...args, ...innerArgs]);</span><br><span class="line">      <span class="keyword">delete</span> context[fn];</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">  <span class="comment">// 如果绑定的是构造函数 那么需要继承构造函数原型属性和方法</span></span><br><span class="line">  <span class="comment">// 实现继承的方式: 使用Object.create</span></span><br><span class="line">  result.prototype = <span class="built_in">Object</span>.create(<span class="built_in">this</span>.prototype);</span><br><span class="line">  <span class="keyword">return</span> result;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//用法如下</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// function Person(name, age) &#123;</span></span><br><span class="line"><span class="comment">//   console.log(name); //&#x27;我是参数传进来的name&#x27;</span></span><br><span class="line"><span class="comment">//   console.log(age); //&#x27;我是参数传进来的age&#x27;</span></span><br><span class="line"><span class="comment">//   console.log(this); //构造函数this指向实例对象</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="comment">// // 构造函数原型的方法</span></span><br><span class="line"><span class="comment">// Person.prototype.say = function() &#123;</span></span><br><span class="line"><span class="comment">//   console.log(123);</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="comment">// let obj = &#123;</span></span><br><span class="line"><span class="comment">//   objName: &#x27;我是obj传进来的name&#x27;,</span></span><br><span class="line"><span class="comment">//   objAge: &#x27;我是obj传进来的age&#x27;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="comment">// // 普通函数</span></span><br><span class="line"><span class="comment">// function normalFun(name, age) &#123;</span></span><br><span class="line"><span class="comment">//   console.log(name);   //&#x27;我是参数传进来的name&#x27;</span></span><br><span class="line"><span class="comment">//   console.log(age);   //&#x27;我是参数传进来的age&#x27;</span></span><br><span class="line"><span class="comment">//   console.log(this); //普通函数this指向绑定bind的第一个参数 也就是例子中的obj</span></span><br><span class="line"><span class="comment">//   console.log(this.objName); //&#x27;我是obj传进来的name&#x27;</span></span><br><span class="line"><span class="comment">//   console.log(this.objAge); //&#x27;我是obj传进来的age&#x27;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 先测试作为构造函数调用</span></span><br><span class="line"><span class="comment">// let bindFun = Person.myBind(obj, &#x27;我是参数传进来的name&#x27;)</span></span><br><span class="line"><span class="comment">// let a = new bindFun(&#x27;我是参数传进来的age&#x27;)</span></span><br><span class="line"><span class="comment">// a.say() //123</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 再测试作为普通函数调用</span></span><br><span class="line"><span class="comment">// let bindFun = normalFun.myBind(obj, &#x27;我是参数传进来的name&#x27;)</span></span><br><span class="line"><span class="comment">//  bindFun(&#x27;我是参数传进来的age&#x27;)</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="3-47-RAF-和-RIC-是什么"><a href="#3-47-RAF-和-RIC-是什么" class="headerlink" title="3.47 RAF 和 RIC 是什么"></a>3.47 RAF 和 RIC 是什么</h2><p><strong>requestAnimationFrame：</strong> 告诉浏览器在下次重绘之前执行传入的回调函数(通常是操纵 dom，更新动画的函数)；由于是每帧执行一次，那结果就是每秒的执行次数与浏览器屏幕刷新次数一样，通常是每秒 60 次。</p>
<p><strong>requestIdleCallback：</strong>: 会在浏览器空闲时间执行回调，也就是允许开发人员在主事件循环中执行低优先级任务，而不影响一些延迟关键事件。如果有多个回调，会按照先进先出原则执行，但是当传入了 timeout，为了避免超时，有可能会打乱这个顺序。</p>
<blockquote>
<p>这个题目可以深入去问浏览器每一帧的渲染流程 具体可以看看这篇 <a target="_blank" rel="noopener" href="https://juejin.cn/post/6844903848981577735">requestIdleCallback 和 requestAnimationFrame 详解</a></p>
</blockquote>
<h1 id="四、网络请求"><a href="#四、网络请求" class="headerlink" title="四、网络请求"></a>四、网络请求</h1><h2 id="4-1-http中post请求和get请求有什么区别"><a href="#4-1-http中post请求和get请求有什么区别" class="headerlink" title="4.1 http中post请求和get请求有什么区别"></a>4.1 http中post请求和get请求有什么区别</h2><p>（1）post更安全（不会作为url的一部分，不会被缓存、保存在服务器日志、以及浏览器浏览记录中）</p>
<p>（2）post发送的数据更大（get有url长度限制）</p>
<p>（3）post能发送更多的数据类型（get只能发送ASCII字符）</p>
<p>（4）post比get慢</p>
<p>（5）post用于修改和写入数据，get一般用于搜索排序和筛选之类的操作（淘宝，支付宝的搜索查询都是get提交），目的是资源的获取，读取数据</p>
<h2 id="4-2-从输入一个-URL-地址到浏览器完成渲染的整个过程？"><a href="#4-2-从输入一个-URL-地址到浏览器完成渲染的整个过程？" class="headerlink" title="4.2 从输入一个 URL 地址到浏览器完成渲染的整个过程？"></a>4.2 从输入一个 URL 地址到浏览器完成渲染的整个过程？</h2><p>浏览器地址栏输入 URL 并回车</p>
<p>浏览器查找当前 URL 是否存在缓存，并比较缓存是否过期</p>
<p>DNS 解析 URL 对应的 IP</p>
<p>根据 IP 建立 TCP 连接（三次握手）</p>
<p>发送 http 请求</p>
<p>服务器处理请求，浏览器接受 HTTP 响应</p>
<p>浏览器解析并渲染页面</p>
<p>关闭 TCP 连接（四次握手）</p>
<h2 id="4-3-使用什么工具进行post请求的测试"><a href="#4-3-使用什么工具进行post请求的测试" class="headerlink" title="4.3 使用什么工具进行post请求的测试"></a>4.3 使用什么工具进行post请求的测试</h2><p>postman</p>
<h2 id="4-4-http状态码有哪些"><a href="#4-4-http状态码有哪些" class="headerlink" title="4.4 http状态码有哪些"></a>4.4 http状态码有哪些</h2><p>1开头    表示临时响应并需要请求者继续执行操作的状态码。</p>
<p>2开头 （请求成功）表示成功处理了请求的状态代码。</p>
<p>3开头 （请求被重定向）表示要完成请求，需要进一步操作。 通常，这些状态代码用来重定向。</p>
<p>4开头 （请求错误）这些状态代码表示请求可能出错，妨碍了服务器的处理。</p>
<p>5开头（服务器错误）这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误，而不是请求出错。</p>
<ul>
<li>常见状态码</li>
</ul>
<p>http 状态码 200 （有内容） 服务器成功处理了请求</p>
<p>http 状态码 204 （无内容） 服务器成功处理了请求，但没有返回任何内容</p>
<p>http 状态码 301 （永久移动） 请求的网页已永久移动到新位置。 服务器返回此响应（对 GET 或 HEAD 请求的响应）时，会自动将请求者转到新位置。</p>
<p>http 状态码 302 （临时移动） 服务器目前从不同位置的网页响应请求，但请求者应继续使用原有位置来进行以后的请求。</p>
<p>http 状态码 304 （未修改） 自从上次请求后，请求的网页未修改过。 服务器返回此响应时，不会返回网页内容。</p>
<p>http 状态码 400 （错误请求） 服务器不理解请求的语法（一般为参数错误）。</p>
<p>http 状态码 401 （未授权） 请求要求身份验证。 对于需要登录的网页，服务器可能返回此响应。</p>
<p>http 状态码 403 （禁止） 服务器拒绝请求。（一般为客户端的用户权限不够）</p>
<p>http 状态码 404 （未找到） 服务器找不到请求的网页。</p>
<p>http 状态码 500（服务器内部错误）  服务器遇到错误，无法完成请求。</p>
<h2 id="4-5-怎么解决跨域问题"><a href="#4-5-怎么解决跨域问题" class="headerlink" title="4.5 怎么解决跨域问题"></a>4.5 怎么解决跨域问题</h2><ul>
<li>后台cors</li>
<li>前端使用jsonp请求（后台接口必须支持jsonp）</li>
<li>使用反向代理方式</li>
</ul>
<h2 id="4-6-http和TCP协议都什么区别"><a href="#4-6-http和TCP协议都什么区别" class="headerlink" title="4.6  http和TCP协议都什么区别"></a>4.6  http和TCP协议都什么区别</h2><p>HTTP是基于TCP的，客户端往服务端发送一个HTTP请求时第一步就是要建立与服务端的TCP连接，也就是先三次握手，“你好，你好，你好”。从HTTP 1.1开始支持持久连接，也就是一次TCP连接可以发送多次的HTTP请求。</p>
<p>小总结：HTTP基于TCP</p>
<p>需要说出TCP三次握手四次挥手。</p>
<h2 id="4-7-http和https有什么区别"><a href="#4-7-http和https有什么区别" class="headerlink" title="4.7 http和https有什么区别"></a>4.7 http和https有什么区别</h2><ul>
<li><p>HTTP是<code>明文传输</code>，不安全的，HTTPS是<code>加密传输</code>，安全的多</p>
</li>
<li><p>HTTP标准端口是<code>80</code>，HTTPS标准端口是<code>443</code></p>
</li>
<li><p>HTTP不用认证证书<code>免费</code>，HTTPS需要认证证书<code>要钱</code></p>
</li>
<li><p>连接方式不同，HTTP三次握手，HTTPS中TLS1.2版本7次，TLS1.3版本6次</p>
</li>
<li><p>HTTP在OSI网络模型中是在<code>应用层</code>，而HTTPS的TLS是在<code>传输层</code></p>
</li>
<li><p>HTTP是<code>无状态</code>的，HTTPS是<code>有状态</code>的</p>
</li>
</ul>
<h2 id="4-8-http和websocket协议有什么区别"><a href="#4-8-http和websocket协议有什么区别" class="headerlink" title="4.8 http和websocket协议有什么区别"></a>4.8 http和websocket协议有什么区别</h2><p>区分这两个概念是比较有意义的，毕竟TCP看不见摸不着，HTTP与Socket是实实在在能用到的。</p>
<ul>
<li>HTTP是短连接，Socket(基于TCP协议的)是长连接。尽管HTTP1.1开始支持持久连接，但仍无法保证始终连接。而Socket连接一旦建立TCP三次握手，除非一方主动断开，否则连接状态一直保持。</li>
<li>HTTP连接服务端无法主动发消息，Socket连接双方请求的发送先后限制。这点就比较重要了，因为它将决定二者分别适合应用在什么场景下。HTTP采用“请求-响应”机制，在客户端还没发送消息给服务端前，服务端无法推送消息给客户端。必须满足客户端发送消息在前，服务端回复在后。Socket连接双方类似peer2peer的关系，一方随时可以向另一方喊话。<ul>
<li>用HTTP的情况：双方不需要时刻保持连接在线，比如客户端资源的获取、文件上传等。</li>
<li>用Socket的情况：大部分即时通讯应用(QQ、微信)、聊天室等等。</li>
</ul>
</li>
</ul>
<h2 id="4-9-Ajax请求的步骤是什么？"><a href="#4-9-Ajax请求的步骤是什么？" class="headerlink" title="4.9 Ajax请求的步骤是什么？"></a>4.9 Ajax请求的步骤是什么？</h2><p>1.首先,创建一个XMLHttpRequest异步对象</p>
<p>2.然后,设置请求方式和请求地址</p>
<p>3.接着,用send发送请求</p>
<p>4.然后,监听状态变化</p>
<h2 id="4-10-http的强制缓存和协商缓存是什么？"><a href="#4-10-http的强制缓存和协商缓存是什么？" class="headerlink" title="4.10 http的强制缓存和协商缓存是什么？"></a>4.10 http的强制缓存和协商缓存是什么？</h2><p>参考地址： <a target="_blank" rel="noopener" href="https://juejin.cn/post/6974529351270268958#heading-20">https://juejin.cn/post/6974529351270268958#heading-20</a></p>
<ul>
<li>强制缓存就是文件直接从本地缓存中获取，不需要发送请求。</li>
</ul>
<p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b5f04f37b588462ab7abf025cfa7c5a8~tplv-k3u1fbpfcp-watermark.awebp" alt="强制缓存 图1"></p>
<p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2a925e79ee724f1099df19d9e61fff32~tplv-k3u1fbpfcp-watermark.awebp" alt="强制缓存 图2"></p>
<p>从上图中可以看到，此时浏览器已经接收到 <code>cache-control</code> 的值，那么这个时候浏览器再次发送请求时，它会先检查它的 <code>cache-control</code> 是否过期，如果没有过期则直接从本地缓存中拉取资源，返回到客户端，而无需再经过服务器。</p>
<ul>
<li><p>协商缓存，也叫对比缓存。</p>
<p>它是一种<strong>服务端的缓存策略</strong>，即通过服务端来判断某件事情是不是可以被缓存。</p>
<p>服务端判断客户端的资源，是否和服务端资源一样，如果一致则返回 <code>304</code> ，反之返回 <code>200</code> 和最新的资源。</p>
</li>
</ul>
<p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5684907367bc4101b4e3f4bc23cdb760~tplv-k3u1fbpfcp-watermark.awebp" alt="协商缓存 图1"></p>
<h2 id="4-11-什么是XSS、CSRF攻击"><a href="#4-11-什么是XSS、CSRF攻击" class="headerlink" title="4.11 什么是XSS、CSRF攻击"></a>4.11 什么是XSS、CSRF攻击</h2><p>CSRF即Cross-site request forgery(跨站请求伪造)，是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。</p>
<p>XSS即Cross Site Scripting（跨站脚本），指的是通过利用网页开发时留下的漏洞，注入恶意指令代码到网页，使用户加载并执行攻击者恶意制造的网页程序。常见的例如在评论区植入JS代码，用户进入评论页时代码被执行，造成页面被植入广告、账号信息被窃取</p>
<p><strong>如何防御CSRF攻击</strong></p>
<ul>
<li><p>验证<code>Token</code>：浏览器请求服务器时，服务器返回一个token，每个请求都需要同时带上token和cookie才会被认为是合法请求</p>
</li>
<li><p>验证<code>Referer</code>：通过验证请求头的Referer来验证来源站点，但请求头很容易伪造</p>
</li>
<li><p>设置<code>SameSite</code>：设置cookie的SameSite，可以让cookie不随跨域请求发出，但浏览器兼容不一</p>
</li>
</ul>
<p><strong>如何防御XSS攻击</strong></p>
<ul>
<li><strong>输入检查</strong>：对输入内容中的<code>&lt;script&gt;&lt;iframe&gt;</code>等标签进行转义或者过滤</li>
<li><strong>设置httpOnly</strong>：很多XSS攻击目标都是窃取用户cookie伪造身份认证，设置此属性可防止JS获取cookie</li>
<li><strong>开启CSP</strong>，即开启白名单，可阻止白名单以外的资源加载和运行</li>
</ul>
<h2 id="4-1-如果使用axios取消请求？"><a href="#4-1-如果使用axios取消请求？" class="headerlink" title="4.1 如果使用axios取消请求？"></a>4.1 如果使用axios取消请求？</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">参考Vue项目</span><br></pre></td></tr></table></figure>

<h2 id="4-2-https-加密过程是怎样的"><a href="#4-2-https-加密过程是怎样的" class="headerlink" title="4.2 https 加密过程是怎样的"></a>4.2 https 加密过程是怎样的</h2><p>参考: <a target="_blank" rel="noopener" href="https://juejin.cn/post/6844904150115827725">https://juejin.cn/post/6844904150115827725</a></p>
<h2 id=""><a href="#" class="headerlink" title=""></a></h2><h1 id="五、Vue面试题"><a href="#五、Vue面试题" class="headerlink" title="五、Vue面试题"></a>五、Vue面试题</h1><h2 id="5-1-Vue常见的指令"><a href="#5-1-Vue常见的指令" class="headerlink" title="5.1 Vue常见的指令"></a>5.1 Vue常见的指令</h2><p>v-text、v-cloak、v-once、v-html、v-on、v-bind</p>
<p>v-text:绑定文本，不能加载标签</p>
<p>v-html:绑定文本，可以加载标签</p>
<p>v-bind: <em><strong>*用于绑定数据和元素属性*</strong></em></p>
<p>v-if:条件判断，为真添加元素，为假删除元素</p>
<p>v-for:循环</p>
<p>v-model:双向数据绑定</p>
<p>v-show:条件判断，为真显示，为假不显示 </p>
<h2 id="5-2-MVC和MVVM"><a href="#5-2-MVC和MVVM" class="headerlink" title="5.2 MVC和MVVM"></a>5.2 MVC和MVVM</h2><p>MVC 全名是 Model View Controller，是模型(model)－视图(view)－控制器(controller)的缩写，一种软件设计典范</p>
<ul>
<li>Model（模型）：是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据</li>
<li>View（视图）：是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的</li>
<li>Controller（控制器）：是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据，控制用户输入，并向模型发送数据</li>
</ul>
<p>MVC 的思想：一句话描述就是 Controller 负责将 Model 的数据用 View 显示出来，换句话说就是在 Controller 里面把 Model 的数据赋值给 View。</p>
<h5 id="MVVM"><a href="#MVVM" class="headerlink" title="MVVM"></a>MVVM</h5><p>MVVM 新增了 VM 类</p>
<ul>
<li>ViewModel 层：做了两件事达到了数据的双向绑定 一是将【模型】转化成【视图】，即将后端传递的数据转化成所看到的页面。实现的方式是：数据绑定。二是将【视图】转化成【模型】，即将所看到的页面转化成后端的数据。实现的方式是：DOM 事件监听。</li>
</ul>
<p>MVVM 与 MVC 最大的区别就是：它实现了 View 和 Model 的自动同步，也就是当 Model 的属性改变时，我们不用再自己手动操作 Dom 元素，来改变 View 的显示，而是改变属性后该属性对应 View 层显示会自动改变（对应Vue数据驱动的思想）</p>
<p>整体看来，MVVM 比 MVC 精简很多，不仅简化了业务与界面的依赖，还解决了数据频繁更新的问题，不用再用选择器操作 DOM 元素。因为在 MVVM 中，View 不知道 Model 的存在，Model 和 ViewModel 也观察不到 View，这种低耦合模式提高代码的可重用性</p>
<h2 id="5-3-1-v-if-与-v-for-为什么不建议一起使用"><a href="#5-3-1-v-if-与-v-for-为什么不建议一起使用" class="headerlink" title="5.3 1. v-if 与 v-for 为什么不建议一起使用"></a>5.3 <strong>1.</strong> v-if 与 v-for 为什么不建议一起使用</h2><p>v-for 和 v-if 不要在同一个标签中使用,因为解析时先解析 v-for (<strong>优先级高</strong>)再解析 v-if (<strong>优先级低</strong>)。如果遇到需要同时使用时可以考虑写成计算属性的方式。</p>
<h2 id="5-4-data为什么必须为函数"><a href="#5-4-data为什么必须为函数" class="headerlink" title="5.4 data为什么必须为函数"></a>5.4 data为什么必须为函数</h2><p>组件中的 data 写成一个函数，数据以函数返回值形式定义，这样每复用一次组件，就会返回一份新的 data，类似于给每个组件实例创建一个私有的数据空间，让各个组件实例维护各自的数据。而单纯的写成对象形式，就使得所有组件实例共用了一份 data，就会造成一个变了全都会变的结果</p>
<h2 id="5-5-插槽有哪些？"><a href="#5-5-插槽有哪些？" class="headerlink" title="5.5 插槽有哪些？"></a>5.5 插槽有哪些？</h2><p>设置在自组件内部的<code>插槽</code>像一个盒子，位置由子组件决定，放什么内容由父组件决定。</p>
<p>实现了内容分发，提高了组件自定义的程度，让组件变的更加灵活</p>
<ol>
<li><strong>默认插槽：</strong></li>
</ol>
<p>无需<code>name</code>属性，取子组件肚子里第一个元素节点作为默认插槽。</p>
<p>​    2.<strong>具名插槽：</strong></p>
<p>在多个插槽的情况下使用，利用<code>name</code>标识插槽。</p>
<p>​    3. <strong>作用域插槽：</strong></p>
<p>子组件给父组件传递数据。</p>
<h2 id="5-6-1-Vue循环的key作用"><a href="#5-6-1-Vue循环的key作用" class="headerlink" title="5.6 1. Vue循环的key作用"></a>5.6 <strong>1.</strong> Vue循环的key作用</h2><p>如果不使用 key，Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。key 是为 Vue 中 vnode 的唯一标记，通过这个 key，我们的 diff 操作可以更准确、更快速</p>
<p><strong>更准确</strong>：因为带 key 就不是就地复用了，在 sameNode 函数 a.key === b.key 对比中可以避免就地复用的情况。所以会更加准确。</p>
<p><strong>更快速</strong>：利用 key 的唯一性生成 map 对象来获取对应节点，比遍历方式更快</p>
<h2 id="5-7-Vue双向数据绑定原理（响应式原理）"><a href="#5-7-Vue双向数据绑定原理（响应式原理）" class="headerlink" title="5.7 Vue双向数据绑定原理（响应式原理）"></a>5.7 Vue双向数据绑定原理（响应式原理）</h2><p><strong>一：</strong>整体思路是数据劫持+观察者模式</p>
<p>对象内部通过 defineReactive 方法，使用 Object.defineProperty 将属性进行劫持（只会劫持已经存在的属性），数组则是通过重写数组方法来实现。当页面使用对应属性时，每个属性都拥有自己的 dep 属性，存放他所依赖的 watcher（依赖收集），当属性变化后会通知自己对应的 watcher 去更新(派发更新)。</p>
<p><strong>二：</strong>原理:采用数据劫持，结合发布者-订阅者模式的方式，通过Object.defineProperty（）来劫持各个属性的setter/getter，在数据变动时发布消息给订阅者，触发相应监听回调。</p>
<p>当把一个普通 js对象传给 Vue 实例来作为它的 data 选项时，Vue 将遍历它的属性，用 Object.defineProperty（） 将它们转为 setter/getter。</p>
<p>用户看不到 setter/getter，但是在内部它们让 Vue 追踪依赖，在属性被访问和修改时通知变化。</p>
<h2 id="5-8-Vue生命周期钩子函数"><a href="#5-8-Vue生命周期钩子函数" class="headerlink" title="5.8 Vue生命周期钩子函数"></a>5.8 Vue生命周期钩子函数</h2><p><strong>beforeCreate</strong> 在实例初始化之后，数据观测(data observer) 和 event/watcher 事件配置之前被调用。在当前阶段 data、methods、computed 以及 watch 上的数据和方法都不能被访问</p>
<p><strong>created</strong> 实例已经创建完成之后被调用。在这一步，实例已完成以下的配置：数据观测(data observer)，属性和方法的运算， watch/event 事件回调。这里没有$el,如果非要想与 Dom 进行交互，可以通过 vm.$nextTick 来访问 Dom</p>
<p><strong>beforeMount</strong> 在挂载开始之前被调用：相关的 render 函数首次被调用。</p>
<p><strong>mounted</strong> 在挂载完成后发生，在当前阶段，真实的 Dom 挂载完毕，数据完成双向绑定，可以访问到 Dom 节点</p>
<p><strong>beforeUpdate</strong> 数据更新时调用，发生在虚拟 DOM 重新渲染和打补丁（patch）之前。可以在这个钩子中进一步地更改状态，这不会触发附加的重渲染过程</p>
<p><strong>updated</strong> 发生在更新完成之后，当前阶段组件 Dom 已完成更新。要注意的是避免在此期间更改数据，因为这可能会导致无限循环的更新，该钩子在服务器端渲染期间不被调用。</p>
<p><strong>beforeDestroy</strong> 实例销毁之前调用。在这一步，实例仍然完全可用。我们可以在这时进行善后收尾工作，比如清除计时器。</p>
<p><strong>destroyed</strong> Vue 实例销毁后调用。调用后，Vue 实例指示的所有东西都会解绑定，所有的事件监听器会被移除，所有的子实例也会被销毁。 该钩子在服务器端渲染期间不被调用。</p>
<p><strong>activated</strong> keep-alive 专属，组件被激活时调用</p>
<p><strong>deactivated</strong> keep-alive 专属，组件被销毁时调用</p>
<h2 id="5-9-Vue组件之间数据传递的方式有几种？"><a href="#5-9-Vue组件之间数据传递的方式有几种？" class="headerlink" title="5.9 Vue组件之间数据传递的方式有几种？"></a>5.9 Vue组件之间数据传递的方式有几种？</h2><p>props 和$emit 父组件向子组件传递数据是通过 prop 传递的，子组件传递数据给父组件是通过$emit 触发事件来做到的</p>
<p>$parent,$children 获取当前组件的父组件和当前组件的子组件</p>
<p>$attrs 和$listeners A-&gt;B-&gt;C。Vue 2.4 开始提供了$attrs 和$listeners 来解决这个问题</p>
<p>父组件中通过 provide 来提供变量，然后在子组件中通过 inject 来注入变量。(官方不推荐在实际业务中使用，但是写组件库时很常用)</p>
<p>$refs 获取组件实例</p>
<p>eventBus 兄弟组件数据传递 这种情况下可以使用事件总线的方式</p>
<p>vuex 状态管理</p>
<h2 id="5-10-VueRouter-路由守卫有哪些？执行顺序是什么？"><a href="#5-10-VueRouter-路由守卫有哪些？执行顺序是什么？" class="headerlink" title="5.10 VueRouter 路由守卫有哪些？执行顺序是什么？"></a>5.10 VueRouter 路由守卫有哪些？执行顺序是什么？</h2><p>1、全局守卫</p>
<p>​    beforeEach     全局前置守卫</p>
<p>​    beforeResolve    全局解析守卫</p>
<p>​    afterEach      全局后置守卫</p>
<p>2、独享守卫  </p>
<p>​    beforeEnter</p>
<p>3、 组件内守卫</p>
<p>​    beforeRouteEnter        组件前置守卫 (该守卫没有this)     </p>
<p>​    beforeRouteUpdate      路由改变但是组件被复用时      </p>
<p>​    beforeRouteLeave        组件后置守卫</p>
<p><strong>完整的导航解析流程:</strong></p>
<ol>
<li>导航被触发。</li>
<li>在失活的组件里调用 beforeRouteLeave 守卫。</li>
<li>调用全局的 beforeEach 守卫。</li>
<li>在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。</li>
<li>在路由配置里调用 beforeEnter。</li>
<li>解析异步路由组件。</li>
<li>在被激活的组件里调用 beforeRouteEnter。</li>
<li>调用全局的 beforeResolve 守卫 (2.5+)。</li>
<li>导航被确认。</li>
<li>调用全局的 afterEach 钩子。</li>
<li>触发 DOM 更新。</li>
<li>调用 beforeRouteEnter 守卫中传给 next 的回调函数，创建好的组件实例会作为回调函数的参数传入。</li>
</ol>
<h2 id="5-11-Vue当中的状态管理的作用，以及属性的作用是什么？"><a href="#5-11-Vue当中的状态管理的作用，以及属性的作用是什么？" class="headerlink" title="5.11  Vue当中的状态管理的作用，以及属性的作用是什么？"></a>5.11  Vue当中的状态管理的作用，以及属性的作用是什么？</h2><p>vuex 是专门为 vue 提供的全局状态管理系统，用于多个组件中数据共享、数据缓存等。（无法持久化、内部核心原理是通过创造一个全局实例 new Vue）</p>
<p>主要包括以下几个模块：</p>
<ul>
<li>State：定义了应用状态的数据结构，可以在这里设置默认的初始状态。</li>
<li>Getter：允许组件从 Store 中获取数据，mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。</li>
<li>Mutation：是唯一更改 store 中状态的方法，且必须是同步函数。</li>
<li>Action：用于提交 mutation，而不是直接变更状态，可以包含任意异步操作。</li>
<li>Module：允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。</li>
</ul>
<h2 id="5-12-Vue项目当中怎么解决跨域问题？"><a href="#5-12-Vue项目当中怎么解决跨域问题？" class="headerlink" title="5.12  Vue项目当中怎么解决跨域问题？"></a>5.12  Vue项目当中怎么解决跨域问题？</h2><p>在前后端分离的网站架构中，服务器经常要配置反向代理，使前端通过固定地址访问后端接口，这样后端服务可以采取负载均衡等性能优化措施，对前端应用透明。</p>
<p>假设前端服务器地址为：<code>http://127.0.0.1:8080</code>，后端实际服务地址为：<code>http://server/web-service/userList</code> ，由于涉及到跨域的问题，前端无法直接发http请求给此地址，只能发送同域下的api请求例如：<code>http://127.0.0.1:8080/api/userList</code>， 通过上文介绍，我们了解到需要在前端服务器上配置反向代理，实现将api请求转发至后台服务器的目的。</p>
<p>在vue.config.js中配置:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">    <span class="attr">devServer</span>: &#123;</span><br><span class="line">        <span class="comment">// 配置反向代理</span></span><br><span class="line">        <span class="attr">proxy</span>: &#123;</span><br><span class="line">            <span class="string">&#x27;/ajax&#x27;</span>: &#123;  <span class="comment">// 以/ajax开头的请求</span></span><br><span class="line">                <span class="attr">target</span>: <span class="string">&#x27;https://m.maoyan.com&#x27;</span>,  <span class="comment">// 以/ajax开头的请求，全部代理到https://m.maoyan.com上</span></span><br><span class="line">                <span class="comment">// ws: true,</span></span><br><span class="line">                <span class="attr">changeOrigin</span>: <span class="literal">true</span></span><br><span class="line">            &#125;,</span><br><span class="line">            <span class="string">&#x27;/foo&#x27;</span>: &#123;</span><br><span class="line">                <span class="attr">target</span>: <span class="string">&#x27;&lt;other_url&gt;&#x27;</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h2 id="5-13-Vue项目怎么打包app？"><a href="#5-13-Vue项目怎么打包app？" class="headerlink" title="5.13  Vue项目怎么打包app？"></a>5.13  Vue项目怎么打包app？</h2><ul>
<li><p>修改打包后资源引用为相对路径</p>
<p>Vue.config.js 将<code>baseUrl</code>改为<code>&#39;./&#39;</code></p>
</li>
<li><p>用webpack将项目打包为dist文件</p>
<p>npm run build</p>
</li>
<li><p>打开Huilder 点击打开目录 找到刚刚的dist文件夹，取好项目名称。</p>
</li>
<li><p>右点击项目，将项目转换为App</p>
</li>
<li><p>然后进行mainfest文件配置，制作app图标和启动页 点击进行云打包进行打包</p>
</li>
<li><p>然后下载打包好之后的.apk文件即可。</p>
</li>
</ul>
<h2 id="5-14-怎么解决打包空白问题？"><a href="#5-14-怎么解决打包空白问题？" class="headerlink" title="5.14  怎么解决打包空白问题？"></a>5.14  怎么解决打包空白问题？</h2><ul>
<li>vue cli4 版本的 配置文件是 vue.config.js , 添加下面红框的内容即可, 将路径设置为相对路径:</li>
</ul>
<p><img src="D:\ftp\210\资料\面试题\watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDA0MDEwNw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p>
<ul>
<li><p>然后 找到 路由配置 index.js 文件 , 如果 mode 设置的是 history 就注释掉</p>
<p><img src="D:\ftp\210\资料\面试题\watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDA0MDEwNw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p>
</li>
<li><p>重新打包</p>
</li>
</ul>
<h2 id="5-15-Vue的diff算法是什么"><a href="#5-15-Vue的diff算法是什么" class="headerlink" title="5.15 Vue的diff算法是什么?"></a>5.15 Vue的diff算法是什么?</h2><p><img src="D:\ftp\210\资料\面试题\1" alt="diff算法.png">  </p>
<h2 id="5-16-v-if-和-v-show-的区别"><a href="#5-16-v-if-和-v-show-的区别" class="headerlink" title="5.16 v-if 和 v-show 的区别"></a>5.16 v-if 和 v-show 的区别</h2><p>v-if 在编译过程中会被转化成三元表达式,条件不满足时不渲染此节点。</p>
<p>v-show 会被编译成指令，条件不满足时控制样式将对应节点隐藏 （display:none）</p>
<p><strong>使用场景</strong></p>
<p>v-if 适用于在运行时很少改变条件，不需要频繁切换条件的场景</p>
<p>v-show 适用于需要非常频繁切换条件的场景</p>
<h2 id="5-17-computed-和-watch-的区别和运用的场景"><a href="#5-17-computed-和-watch-的区别和运用的场景" class="headerlink" title="5.17 computed 和 watch 的区别和运用的场景"></a>5.17 computed 和 watch 的区别和运用的场景</h2><p>computed 是计算属性，依赖其他属性计算值，并且 computed 的值有缓存，只有当计算值变化才会返回内容，它可以设置 getter 和 setter。</p>
<p>watch 监听到值的变化就会执行回调，在回调中可以进行一些逻辑操作。</p>
<p>计算属性一般用在模板渲染中，某个值是依赖了其它的响应式对象甚至是计算属性计算而来；而侦听属性适用于观测某个值的变化去完成一段复杂的业务逻辑</p>
<h2 id="5-18-Vue-如何检测数组变化"><a href="#5-18-Vue-如何检测数组变化" class="headerlink" title="5.18 Vue 如何检测数组变化"></a>5.18 Vue 如何检测数组变化</h2><p>数组考虑性能原因没有用 defineProperty 对数组的每一项进行拦截，而是选择对 7 种数组（push,shift,pop,splice,unshift,sort,reverse）方法进行重写(AOP 切片思想)</p>
<p>所以在 Vue 中修改数组的索引和长度是无法监控到的。需要通过以上 7 种变异方法修改数组才会触发数组对应的 watcher 进行更新</p>
<h2 id="5-19-vue3-0-用过吗-了解多少"><a href="#5-19-vue3-0-用过吗-了解多少" class="headerlink" title="5.19 vue3.0 用过吗 了解多少"></a>5.19 vue3.0 用过吗 了解多少</h2><ul>
<li><p>响应式原理的改变 Vue3.x 使用 Proxy 取代 Vue2.x 版本的 Object.defineProperty</p>
</li>
<li><p>组件选项声明方式 Vue3.x 使用 Composition API setup 是 Vue3.x 新增的一个选项， 他是组件内使用 Composition API 的入口。</p>
</li>
<li><p>模板语法变化 slot 具名插槽语法 自定义指令 v-model 升级</p>
</li>
<li><p>其它方面的更改 Suspense 支持 Fragment（多个根节点）和 Protal（在 dom 其他部分渲染组建内容）组件，针对一些特殊的场景做了处理。 基于 treeshaking 优化，提供了更多的内置功能。</p>
<p>Vue3.0 新特性以及使用经验总结 <a target="_blank" rel="noopener" href="https://juejin.cn/post/6940454764421316644">传送门</a></p>
</li>
</ul>
<h2 id="5-23-Vue3-0-和-2-0-的响应式原理区别"><a href="#5-23-Vue3-0-和-2-0-的响应式原理区别" class="headerlink" title="5.23 Vue3.0 和 2.0 的响应式原理区别"></a>5.23 Vue3.0 和 2.0 的响应式原理区别</h2><p>Vue3.x 改用 Proxy 替代 Object.defineProperty。因为 Proxy 可以直接监听对象和数组的变化，并且有多达 13 种拦截方法。</p>
<p><strong>Proxy的优势</strong>如下:</p>
<ul>
<li>Proxy可以直接监听对象而非属性</li>
<li>Proxy可以直接监听数组的变化</li>
<li>Proxy有多达13种拦截方法,不限于apply、ownKeys、deleteProperty、has等等是Object.defineProperty不具备的</li>
<li>Proxy返回的是一个新对象,我们可以只操作新的对象达到目的,而Object.defineProperty只能遍历对象属性直接修改</li>
<li>Proxy作为新标准将受到浏览器厂商重点持续的性能优化，也就是传说中的新标准的性能红利</li>
</ul>
<p><strong>Object.defineProperty的优势</strong>如下:</p>
<ul>
<li>兼容性好,支持IE9</li>
</ul>
<h2 id="5-24-虚拟-DOM-是什么-有什么优缺点"><a href="#5-24-虚拟-DOM-是什么-有什么优缺点" class="headerlink" title="5.24 虚拟 DOM 是什么 有什么优缺点"></a>5.24 虚拟 DOM 是什么 有什么优缺点</h2><p>由于在浏览器中操作 DOM 是很昂贵的。频繁的操作 DOM，会产生一定的性能问题。这就是虚拟 Dom 的产生原因。Vue2 的 Virtual DOM 借鉴了开源库 snabbdom 的实现。Virtual DOM 本质就是用一个原生的 JS 对象去描述一个 DOM 节点，是对真实 DOM 的一层抽象。</p>
<p><strong>优点：</strong></p>
<ol>
<li>保证性能下限： 框架的虚拟 DOM 需要适配任何上层 API 可能产生的操作，它的一些 DOM 操作的实现必须是普适的，所以它的性能并不是最优的；但是比起粗暴的 DOM 操作性能要好很多，因此框架的虚拟 DOM 至少可以保证在你不需要手动优化的情况下，依然可以提供还不错的性能，即保证性能的下限；</li>
<li>无需手动操作 DOM： 我们不再需要手动去操作 DOM，只需要写好 View-Model 的代码逻辑，框架会根据虚拟 DOM 和 数据双向绑定，帮我们以可预期的方式更新视图，极大提高我们的开发效率；</li>
<li>跨平台： 虚拟 DOM 本质上是 JavaScript 对象,而 DOM 与平台强相关，相比之下虚拟 DOM 可以进行更方便地跨平台操作，例如服务器渲染、weex 开发等等。</li>
</ol>
<p><strong>缺点:</strong></p>
<ol>
<li>无法进行极致优化： 虽然虚拟 DOM + 合理的优化，足以应对绝大部分应用的性能需求，但在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化。</li>
<li>首次渲染大量 DOM 时，由于多了一层虚拟 DOM 的计算，会比 innerHTML 插入慢。</li>
</ol>
<h2 id="5-25-Vuex-页面刷新数据丢失怎么解决"><a href="#5-25-Vuex-页面刷新数据丢失怎么解决" class="headerlink" title="5.25 Vuex 页面刷新数据丢失怎么解决"></a>5.25 Vuex 页面刷新数据丢失怎么解决</h2><p>需要做 vuex 数据持久化 一般使用本地存储的方案来保存数据 可以自己设计存储方案 也可以使用第三方插件</p>
<p>推荐使用 vuex-persist 插件，它就是为 Vuex 持久化存储而生的一个插件。不需要你手动存取 storage ，而是直接将状态保存至 cookie 或者 localStorage 中</p>
<h2 id="5-26-Vuex-为什么要分模块并且加命名空间"><a href="#5-26-Vuex-为什么要分模块并且加命名空间" class="headerlink" title="5.26 Vuex 为什么要分模块并且加命名空间"></a>5.26 Vuex 为什么要分模块并且加命名空间</h2><p><strong>模块</strong>:由于使用单一状态树，应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时，store 对象就有可能变得相当臃肿。为了解决以上问题，Vuex 允许我们将 store 分割成模块（module）。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。</p>
<p><strong>命名空间</strong>：默认情况下，模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。如果希望你的模块具有更高的封装度和复用性，你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后，它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。</p>
<h2 id="5-27-使用过-Vue-SSR-吗？说说-SSR"><a href="#5-27-使用过-Vue-SSR-吗？说说-SSR" class="headerlink" title="5.27 使用过 Vue SSR 吗？说说 SSR"></a>5.27 使用过 Vue SSR 吗？说说 SSR</h2><p>SSR 也就是服务端渲染，也就是将 Vue 在客户端把标签渲染成 HTML 的工作放在服务端完成，然后再把 html 直接返回给客户端。</p>
<p><strong>优点：</strong></p>
<p>SSR 有着更好的 SEO、并且首屏加载速度更快</p>
<p><strong>缺点：</strong> 开发条件会受到限制，服务器端渲染只支持 beforeCreate 和 created 两个钩子，当我们需要一些外部扩展库时需要特殊处理，服务端渲染应用程序也需要处于 Node.js 的运行环境。</p>
<p>服务器会有更大的负载需求</p>
<h2 id="5-28-vue-中使用了哪些设计模式"><a href="#5-28-vue-中使用了哪些设计模式" class="headerlink" title="5.28 vue 中使用了哪些设计模式"></a>5.28 vue 中使用了哪些设计模式</h2><p>1.工厂模式 - 传入参数即可创建实例</p>
<p>虚拟 DOM 根据参数的不同返回基础标签的 Vnode 和组件 Vnode</p>
<p>2.单例模式 - 整个程序有且仅有一个实例</p>
<p>vuex 和 vue-router 的插件注册方法 install 判断如果系统存在实例就直接返回掉</p>
<p>3.发布-订阅模式 (vue 事件机制)</p>
<p>4.观察者模式 (响应式数据原理)</p>
<p>5.装饰模式: (@装饰器的用法)</p>
<p>6.策略模式 策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现方案-比如选项的合并策略</p>
<p>…其他模式欢迎补充</p>
<h2 id="5-29-你都做过哪些-Vue-的性能优化"><a href="#5-29-你都做过哪些-Vue-的性能优化" class="headerlink" title="5.29 你都做过哪些 Vue 的性能优化"></a>5.29 你都做过哪些 Vue 的性能优化</h2><p><strong>一：</strong></p>
<p>对象层级不要过深，否则性能就会差</p>
<p>不需要响应式的数据不要放到 data 中（可以用 Object.freeze() 冻结数据）</p>
<p>v-if 和 v-show 区分使用场景</p>
<p>computed 和 watch 区分使用场景</p>
<p>v-for 遍历必须加 key，key 最好是 id 值，且避免同时使用 v-if</p>
<p>大数据列表和表格性能优化-虚拟列表/虚拟表格</p>
<p>防止内部泄漏，组件销毁后把全局变量和事件销毁</p>
<p>图片懒加载</p>
<p>路由懒加载</p>
<p>第三方插件的按需引入</p>
<p>适当采用 keep-alive 缓存组件</p>
<p>防抖、节流运用</p>
<p>服务端渲染 SSR or 预渲染</p>
<p><strong>二：</strong></p>
<p><strong>编码阶段</strong></p>
<ul>
<li>不要在模板里面写过多表达式</li>
<li>尽量减少<code>data</code>中的数据，<code>data</code>中的数据都会增加<code>getter</code>和<code>setter</code>，会收集对应的<code>watcher</code></li>
<li><code>v-if</code>和<code>v-for</code>不能连用</li>
<li>如果需要使用<code>v-for</code>给每项元素绑定事件时使用事件代理</li>
<li><code>SPA</code> 页面采用<code>keep-alive</code>缓存组件</li>
<li>频繁切换的使用v-show，不频繁切换的使用v-if</li>
<li>循环调用子组件时添加key，<code>key</code>保证唯一</li>
<li>使用路由懒加载、异步组件</li>
<li>防抖、节流</li>
<li>第三方模块按需导入</li>
<li>长列表滚动到可视区域动态加载</li>
<li>图片懒加载</li>
</ul>
<p><strong>SEO优化</strong></p>
<ul>
<li>预渲染</li>
<li>服务端渲染<code>SSR</code>，<code>nuxt.js</code></li>
</ul>
<p><strong>打包优化</strong></p>
<ul>
<li>压缩代码</li>
<li><code>Tree Shaking/Scope Hoisting</code></li>
<li>使用<code>cdn</code>加载第三方模块</li>
<li>多线程打包<code>happypack</code></li>
<li><code>splitChunks</code>抽离公共文件</li>
<li><code>sourceMap</code>优化</li>
</ul>
<p><strong>用户体验</strong></p>
<ul>
<li>骨架屏</li>
<li><code>PWA</code>渐进式Web应用，使用多种技术来增强web app的功能，让网页应用呈现和原生应用相似的体验。</li>
</ul>
<blockquote>
<p>还可以使用缓存(客户端缓存、服务端缓存)优化、服务端开启<code>gzip</code>压缩等。</p>
</blockquote>
<h2 id="5-30-Vue-mixin-的使用场景和原理"><a href="#5-30-Vue-mixin-的使用场景和原理" class="headerlink" title="5.30 Vue.mixin 的使用场景和原理"></a>5.30 Vue.mixin 的使用场景和原理</h2><p>在日常的开发中，我们经常会遇到在不同的组件中经常会需要用到一些相同或者相似的代码，这些代码的功能相对独立，可以通过 Vue 的 mixin 功能抽离公共的业务逻辑，原理类似“对象的继承”，当组件初始化时会调用 mergeOptions 方法进行合并，采用策略模式针对不同的属性进行合并。当组件和混入对象含有同名选项时，这些选项将以恰当的方式进行“合并”。</p>
<h2 id="5-31-nextTick-使用场景和原理"><a href="#5-31-nextTick-使用场景和原理" class="headerlink" title="5.31 nextTick 使用场景和原理"></a>5.31 nextTick 使用场景和原理</h2><p>nextTick 中的回调是在下次 DOM 更新循环结束之后执行的延迟回调。在修改数据之后立即使用这个方法，获取更新后的 DOM。主要思路就是采用微任务优先的方式调用异步方法去执行 nextTick 包装的方法。</p>
<h2 id="5-32-keep-alive-使用场景和原理"><a href="#5-32-keep-alive-使用场景和原理" class="headerlink" title="5.32 keep-alive 使用场景和原理"></a>5.32 keep-alive 使用场景和原理</h2><p>keep-alive 是 Vue 内置的一个组件，可以实现组件缓存，当组件切换时不会对当前组件进行卸载。</p>
<ul>
<li>常用的两个属性 include/exclude，允许组件有条件的进行缓存。</li>
<li>两个生命周期 activated/deactivated，用来得知当前组件是否处于活跃状态。</li>
<li>keep-alive 的中还运用了 LRU(最近最少使用) 算法 （超过keep-alive最大的保存长度就会删除），选择最近最久未使用的组件予以淘汰。</li>
</ul>
<h2 id="5-33-Vue-set-方法原理"><a href="#5-33-Vue-set-方法原理" class="headerlink" title="5.33 Vue.set 方法原理"></a>5.33 Vue.set 方法原理</h2><p>了解 Vue 响应式原理的同学都知道在两种情况下修改数据 Vue 是不会触发视图更新的</p>
<p>1.在实例创建之后添加新的属性到实例上（给响应式对象新增属性）</p>
<p>2.直接更改数组下标来修改数组的值</p>
<p>Vue.set 或者说是$set 原理如下</p>
<p>因为响应式数据 我们给对象和数组本身都增加了__ob__属性，代表的是 Observer 实例。当给对象新增不存在的属性 首先会把新的属性进行响应式跟踪 然后会触发对象__ob__的 dep 收集到的 watcher 去更新，当修改数组索引时我们调用数组本身的 splice 方法去更新数组</p>
<h2 id="5-34-Vue-extend-作用和原理"><a href="#5-34-Vue-extend-作用和原理" class="headerlink" title="5.34 Vue.extend 作用和原理"></a>5.34 Vue.extend 作用和原理</h2><p>官方解释：Vue.extend 使用基础 Vue 构造器，创建一个“子类”。参数是一个包含组件选项的对象。</p>
<p>其实就是一个子类构造器 是 Vue 组件的核心 api 实现思路就是使用原型继承的方法返回了 Vue 的子类 并且利用 mergeOptions 把传入组件的 options 和父类的 options 进行了合并</p>
<h2 id="5-35-写过自定义指令吗-原理是什么"><a href="#5-35-写过自定义指令吗-原理是什么" class="headerlink" title="5.35 写过自定义指令吗 原理是什么"></a>5.35 写过自定义指令吗 原理是什么</h2><p>指令本质上是装饰器，是 vue 对 HTML 元素的扩展，给 HTML 元素增加自定义功能。vue 编译 DOM 时，会找到指令对象，执行指令的相关方法。</p>
<p>自定义指令有五个生命周期（也叫钩子函数），分别是 bind、inserted、update、componentUpdated、unbind</p>
<p>\1. bind：只调用一次，指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。 2. inserted：被绑定元素插入父节点时调用 (仅保证父节点存在，但不一定已被插入文档中)。 3. update：被绑定于元素所在的模板更新时调用，而无论绑定值是否变化。通过比较更新前后的绑定值，可以忽略不必要的模板更新。 4. componentUpdated：被绑定元素所在模板完成一次更新周期时调用。 5. unbind：只调用一次，指令与元素解绑时调用。</p>
<p><strong>原理</strong></p>
<p>1.在生成 ast 语法树时，遇到指令会给当前元素添加 directives 属性</p>
<p>2.通过 genDirectives 生成指令代码</p>
<p>3.在 patch 前将指令的钩子提取到 cbs 中,在 patch 过程中调用对应的钩子</p>
<p>4.当执行指令对应钩子函数时，调用对应指令定义的方法</p>
<h2 id="5-36-Vue-修饰符有哪些"><a href="#5-36-Vue-修饰符有哪些" class="headerlink" title="5.36 Vue 修饰符有哪些"></a>5.36 Vue 修饰符有哪些</h2><p><strong>事件修饰符</strong></p>
<ul>
<li>.stop 阻止事件继续传播</li>
<li>.prevent 阻止标签默认行为</li>
<li>.capture 使用事件捕获模式,即元素自身触发的事件先在此处处理，然后才交由内部元素进行处理</li>
<li>.self 只当在 event.target 是当前元素自身时触发处理函数</li>
<li>.once 事件将只会触发一次</li>
<li>.passive 告诉浏览器你不想阻止事件的默认行为</li>
</ul>
<p><strong>v-model 的修饰符</strong></p>
<ul>
<li>.lazy 通过这个修饰符，转变为在 change 事件再同步</li>
<li>.number 自动将用户的输入值转化为数值类型</li>
<li>.trim 自动过滤用户输入的首尾空格</li>
</ul>
<p><strong>键盘事件的修饰符</strong></p>
<ul>
<li>.enter</li>
<li>.tab</li>
<li>.delete (捕获“删除”和“退格”键)</li>
<li>.esc</li>
<li>.space</li>
<li>.up</li>
<li>.down</li>
<li>.left</li>
<li>.right</li>
</ul>
<p><strong>系统修饰键</strong></p>
<ul>
<li>.ctrl</li>
<li>.alt</li>
<li>.shift</li>
<li>.meta</li>
</ul>
<p><strong>鼠标按钮修饰符</strong></p>
<ul>
<li>.left</li>
<li>.right</li>
<li>.middle</li>
</ul>
<h2 id="5-37-Vue-模板编译原理"><a href="#5-37-Vue-模板编译原理" class="headerlink" title="5.37 Vue 模板编译原理"></a>5.37 Vue 模板编译原理</h2><p>Vue 的编译过程就是将 template 转化为 render 函数的过程 分为以下三步：</p>
<p>第一步是将 模板字符串 转换成 element ASTs（解析器） </p>
<p>第二步是对 AST 进行静态节点标记，主要用来做虚拟DOM的渲染优化（优化器） </p>
<p>第三步是 使用 element ASTs 生成 render 函数代码字符串（代码生成器）</p>
<h2 id="5-38-能说下-vue-router-中常用的路由模式实现原理吗"><a href="#5-38-能说下-vue-router-中常用的路由模式实现原理吗" class="headerlink" title="5.38 能说下 vue-router 中常用的路由模式实现原理吗"></a>5.38 能说下 vue-router 中常用的路由模式实现原理吗</h2><p>vue-router 有 3 种路由模式：hash、history、abstract，对应的源码如下所示：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">switch (mode) &#123;</span><br><span class="line">  case &#x27;history&#x27;:</span><br><span class="line">	this.history = new HTML5History(this, options.base)</span><br><span class="line">	break</span><br><span class="line">  case &#x27;hash&#x27;:</span><br><span class="line">	this.history = new HashHistory(this, options.base, this.fallback)</span><br><span class="line">	break</span><br><span class="line">  case &#x27;abstract&#x27;:</span><br><span class="line">	this.history = new AbstractHistory(this, options.base)</span><br><span class="line">	break</span><br><span class="line">  default:</span><br><span class="line">	if (process.env.NODE_ENV !== &#x27;production&#x27;) &#123;</span><br><span class="line">	  assert(false, `invalid mode: $&#123;mode&#125;`)</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line">复制代码</span><br></pre></td></tr></table></figure>

<p>其中，3 种路由模式的说明如下：</p>
<ul>
<li>hash:  使用 URL hash 值来作路由。支持所有浏览器，包括不支持 HTML5 History Api 的浏览器；</li>
<li>history :  依赖 HTML5 History API 和服务器配置。具体可以查看 HTML5 History 模式；</li>
<li>abstract :  支持所有 JavaScript 运行环境，如 Node.js 服务器端。如果发现没有浏览器的 API，路由会自动强制进入这个模式.</li>
</ul>
<p><strong>hash 模式</strong></p>
<ol>
<li>location.hash 的值实际就是 URL 中#后面的东西 它的特点在于：hash 虽然出现 URL 中，但不会被包含在 HTTP 请求中，对后端完全没有影响，因此改变 hash 不会重新加载页面。</li>
<li>可以为 hash 的改变添加监听事件</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">window</span>.addEventListener(<span class="string">&quot;hashchange&quot;</span>, funcRef, <span class="literal">false</span>);</span><br><span class="line">复制代码</span><br></pre></td></tr></table></figure>

<p>每一次改变 hash（window.location.hash），都会在浏览器的访问历史中增加一个记录利用 hash 的以上特点，就可以来实现前端路由“更新视图但不重新请求页面”的功能了</p>
<blockquote>
<p>特点：兼容性好但是不美观</p>
</blockquote>
<p><strong>history 模式</strong></p>
<p>利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。</p>
<p>这两个方法应用于浏览器的历史记录站，在当前已有的 back、forward、go 的基础之上，它们提供了对历史记录进行修改的功能。这两个方法有个共同的特点：当调用他们修改浏览器历史记录栈后，虽然当前 URL 改变了，但浏览器不会刷新页面，这就为单页应用前端路由“更新视图但不重新请求页面”提供了基础。</p>
<h2 id="5-39-vue3-0-特性你有什么了解的吗？"><a href="#5-39-vue3-0-特性你有什么了解的吗？" class="headerlink" title="5.39 vue3.0 特性你有什么了解的吗？"></a>5.39 vue3.0 特性你有什么了解的吗？</h2><ul>
<li>响应式原理的改变 Vue3.x 使用 Proxy 取代 Vue2.x 版本的 Object.defineProperty</li>
<li>组件选项声明方式 Vue3.x 使用 Composition API setup 是 Vue3.x 新增的一个选项， 他是组件内使用 Composition API 的入口。</li>
<li>模板语法变化 slot 具名插槽语法 自定义指令 v-model 升级</li>
<li>其它方面的更改 Suspense 支持 Fragment（多个根节点）和 Protal（在 dom 其他部分渲染组建内容）组件，针对一些特殊的场景做了处理。 基于 treeshaking 优化，提供了更多的内置功能。</li>
</ul>
<p>Vue3.0 新特性以及使用经验总结 <a target="_blank" rel="noopener" href="https://juejin.cn/post/6940454764421316644">传送门</a></p>
<h2 id="5-40-说说你对-SPA-单页面的理解，它的优缺点分别是什么？"><a href="#5-40-说说你对-SPA-单页面的理解，它的优缺点分别是什么？" class="headerlink" title="5.40 说说你对 SPA 单页面的理解，它的优缺点分别是什么？"></a>5.40 说说你对 SPA 单页面的理解，它的优缺点分别是什么？</h2><p>SPA（ single-page application ）仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成，SPA 不会因为用户的操作而进行页面的重新加载或跳转；取而代之的是利用路由机制实现 HTML 内容的变换，UI 与用户的交互，避免页面的重新加载。</p>
<p><strong>优点：</strong></p>
<ul>
<li>用户体验好、快，内容的改变不需要重新加载整个页面，避免了不必要的跳转和重复渲染；</li>
<li>基于上面一点，SPA 相对对服务器压力小；</li>
<li>前后端职责分离，架构清晰，前端进行交互逻辑，后端负责数据处理；</li>
</ul>
<p><strong>缺点：</strong></p>
<ul>
<li>初次加载耗时多：为实现单页 Web 应用功能及显示效果，需要在加载页面的时候将 JavaScript、CSS 统一加载，部分页面按需加载；</li>
<li>前进后退路由管理：由于单页应用在一个页面中显示所有的内容，所以不能使用浏览器的前进后退功能，所有的页面切换需要自己建立堆栈管理；</li>
<li>SEO 难度较大：由于所有的内容都在一个页面中动态替换显示，所以在 SEO 上其有着天然的弱势。</li>
</ul>
<h2 id="5-41-route和-router的区别"><a href="#5-41-route和-router的区别" class="headerlink" title="5.41 $route和$router的区别"></a>5.41 <code>$route</code>和<code>$router</code>的区别</h2><ul>
<li>$route是<code>路由信息对象</code>，包括path，params，hash，query，fullPath，matched，name等路由信息参数。</li>
<li>而$router是<code>路由实例</code>对象包括了路由的跳转方法，钩子函数等。</li>
</ul>
<h2 id="5-42-vue-router路由懒加载"><a href="#5-42-vue-router路由懒加载" class="headerlink" title="5.42 vue-router路由懒加载"></a>5.42 vue-router路由懒加载</h2><p>像 vue 这种单页面应用，如果没有路由懒加载，运用 webpack 打包后的文件将会很大，造成进入首页时，需要加载的内容过多，出现较长时间的白屏，运用路由懒加载则可以将页面进行划分，需要的时候才加载页面，可以有效的分担首页所承担的加载压力，减少首页加载用时。</p>
<ul>
<li>参考: <a target="_blank" rel="noopener" href="https://juejin.cn/post/6895546761255845901#heading-4">vue路由懒加载</a></li>
</ul>
<p>vue 路由懒加载有以下三种方式：</p>
<ol>
<li>vue 异步组件</li>
<li>ES6 的 import()</li>
<li>webpack 的 require.ensure()</li>
</ol>
<h2 id="5-43-Vue-Diff算法？"><a href="#5-43-Vue-Diff算法？" class="headerlink" title="5.43 Vue Diff算法？"></a>5.43 Vue Diff算法？</h2><p>参考: <a target="_blank" rel="noopener" href="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9e3c68d1b0884d9ca0f8ffc5ee64a28e~tplv-k3u1fbpfcp-watermark.awebp">https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9e3c68d1b0884d9ca0f8ffc5ee64a28e~tplv-k3u1fbpfcp-watermark.awebp</a></p>
<p>参考: <a target="_blank" rel="noopener" href="https://juejin.cn/post/6953433215218483236">https://juejin.cn/post/6953433215218483236</a></p>
<h2 id="5-44-如何使用v-model封装自定义组件或者UI组件？（二次封装）"><a href="#5-44-如何使用v-model封装自定义组件或者UI组件？（二次封装）" class="headerlink" title="5.44 如何使用v-model封装自定义组件或者UI组件？（二次封装）"></a>5.44 如何使用v-model封装自定义组件或者UI组件？（二次封装）</h2><p>参考: <a target="_blank" rel="noopener" href="https://www.jianshu.com/p/f288b27171b3">https://www.jianshu.com/p/f288b27171b3</a></p>
<h1 id="六、项目内容"><a href="#六、项目内容" class="headerlink" title="六、项目内容"></a>六、项目内容</h1><h2 id="6-1-Vue项目的难点有哪些？"><a href="#6-1-Vue项目的难点有哪些？" class="headerlink" title="6.1 Vue项目的难点有哪些？"></a>6.1 Vue项目的难点有哪些？</h2><h2 id="6-2-Vue项目上线之前做了哪些优化？"><a href="#6-2-Vue项目上线之前做了哪些优化？" class="headerlink" title="6.2 Vue项目上线之前做了哪些优化？"></a>6.2 Vue项目上线之前做了哪些优化？</h2><h2 id="6-3-uniapp项目的难点有哪些？"><a href="#6-3-uniapp项目的难点有哪些？" class="headerlink" title="6.3 uniapp项目的难点有哪些？"></a>6.3 uniapp项目的难点有哪些？</h2><h2 id="6-4-uniapp项目上线之前做了哪些优化？"><a href="#6-4-uniapp项目上线之前做了哪些优化？" class="headerlink" title="6.4 uniapp项目上线之前做了哪些优化？"></a>6.4 uniapp项目上线之前做了哪些优化？</h2><p><a target="_blank" rel="noopener" href="https://juejin.cn/post/6997224351346982942">https://juejin.cn/post/6997224351346982942</a></p>
<h2 id="6-5-Webpack-有哪些优化手段"><a href="#6-5-Webpack-有哪些优化手段" class="headerlink" title="6.5 Webpack 有哪些优化手段"></a>6.5 Webpack 有哪些优化手段</h2><p>参考： <a target="_blank" rel="noopener" href="https://juejin.cn/post/6844904093463347208">https://juejin.cn/post/6844904093463347208</a></p>
<h2 id="6-6-babel-是什么，原理了解吗"><a href="#6-6-babel-是什么，原理了解吗" class="headerlink" title="6.6 babel 是什么，原理了解吗"></a>6.6 babel 是什么，原理了解吗</h2><p>Babel 是一个 JavaScript 编译器。他把最新版的 javascript 编译成当下可以执行的版本，简言之，利用 babel 就可以让我们在当前的项目中随意的使用这些新最新的 es6，甚至 es7 的语法。</p>
<p>Babel 的三个主要处理步骤分别是： 解析（parse），转换（transform），生成（generate）。</p>
<ul>
<li>解析 将代码解析成抽象语法树（AST），每个 js 引擎（比如 Chrome 浏览器中的 V8 引擎）都有自己的 AST 解析器，而 Babel 是通过 Babylon 实现的。在解析过程中有两个阶段：词法分析和语法分析，词法分析阶段把字符串形式的代码转换为令牌（tokens）流，令牌类似于 AST 中节点；而语法分析阶段则会把一个令牌流转换成 AST 的形式，同时这个阶段会把令牌中的信息转换成 AST 的表述结构。</li>
<li>转换 在这个阶段，Babel 接受得到 AST 并通过 babel-traverse 对其进行深度优先遍历，在此过程中对节点进行添加、更新及移除操作。这部分也是 Babel 插件介入工作的部分。</li>
<li>生成 将经过转换的 AST 通过 babel-generator 再转换成 js 代码，过程就是深度优先遍历整个 AST，然后构建可以表示转换后代码的字符串。</li>
</ul>
<p>还想深入了解的可以看 [<a target="_blank" rel="noopener" href="https://juejin.cn/post/6844903760603398151">实践系列]Babel 原理</a></p>
<h1 id="七、设计模式"><a href="#七、设计模式" class="headerlink" title="七、设计模式"></a>七、设计模式</h1><h2 id="7-1-观察者模式、发布-订阅模式篇"><a href="#7-1-观察者模式、发布-订阅模式篇" class="headerlink" title="7.1 观察者模式、发布-订阅模式篇"></a>7.1 观察者模式、发布-订阅模式篇</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@description </span>观察者模式实现</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">// 目标对象</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Subject</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="title">constructor</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">        <span class="comment">// 维护一个观察者集合</span></span><br><span class="line">        <span class="built_in">this</span>.observerList = [];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 添加观察者</span></span><br><span class="line">    <span class="function"><span class="title">addObserver</span>(<span class="params">observer</span>)</span> &#123;</span><br><span class="line">        <span class="comment">// 避免重复添加观察者</span></span><br><span class="line">        <span class="keyword">if</span>(<span class="built_in">this</span>.observerList.includes(observer)) <span class="keyword">return</span>;</span><br><span class="line">        <span class="built_in">this</span>.observerList.push(observer);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 删除指定观察者，不支持全部删除，风险较高</span></span><br><span class="line">    <span class="function"><span class="title">removeObserver</span>(<span class="params">observer</span>)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span>(!observer) <span class="keyword">return</span>;</span><br><span class="line">        <span class="built_in">this</span>.observerList = <span class="built_in">this</span>.observerList.filter(<span class="function"><span class="params">i</span> =&gt;</span> i !== observer);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 通知观察者</span></span><br><span class="line">    <span class="function"><span class="title">notify</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">        <span class="comment">// 若无观察者，也就不通知了</span></span><br><span class="line">        <span class="keyword">if</span>(!<span class="built_in">this</span>.observerList) <span class="keyword">return</span>;</span><br><span class="line">        <span class="comment">// 遍历调用观察者的 update 方法</span></span><br><span class="line">        <span class="built_in">this</span>.observerList.forEach(<span class="function"><span class="params">observer</span> =&gt;</span> &#123;</span><br><span class="line">            <span class="keyword">if</span>(observer.update &amp;&amp; <span class="built_in">Object</span>.prototype.toString.call(observer.update).slice(<span class="number">8</span>, -<span class="number">1</span>) === <span class="string">&quot;Function&quot;</span>) &#123;</span><br><span class="line">                observer.update();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 观察者</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Observer</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="title">update</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&quot;我观察到了目标对象的变化&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">作者：博小魏</span><br><span class="line">链接：https:<span class="comment">//juejin.cn/post/7035247560918990884</span></span><br><span class="line">来源：稀土掘金</span><br><span class="line">著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。</span><br></pre></td></tr></table></figure>

<h2 id="7-2-单例模式"><a href="#7-2-单例模式" class="headerlink" title="7.2 单例模式"></a>7.2 单例模式</h2><p>顾名思义单例就是多次执行都只会生成这一个对象。</p>
<p>参考地址: <a target="_blank" rel="noopener" href="https://blog.csdn.net/loringray/article/details/104585104">https://blog.csdn.net/loringray/article/details/104585104</a></p>
<h2 id="7-3-工厂模式"><a href="#7-3-工厂模式" class="headerlink" title="7.3 工厂模式"></a>7.3 工厂模式</h2><p>参考:  <a target="_blank" rel="noopener" href="https://segmentfault.com/a/1190000012422198">https://segmentfault.com/a/1190000012422198</a></p>
<h1 id="八、Typescript"><a href="#八、Typescript" class="headerlink" title="八、Typescript"></a>八、Typescript</h1><h2 id="8-1-ts中的访问修饰符"><a href="#8-1-ts中的访问修饰符" class="headerlink" title="8.1 ts中的访问修饰符"></a>8.1 ts中的访问修饰符</h2><ul>
<li>public，任何地方</li>
<li>private，只能在类的内部访问</li>
<li>protected，能在类的内部访问和子类中访问</li>
<li>readonly，属性设置为只读</li>
</ul>
<h2 id="8-2-const和readonly的区别"><a href="#8-2-const和readonly的区别" class="headerlink" title="8.2 const和readonly的区别"></a>8.2 const和readonly的区别</h2><ul>
<li><p>const用于变量，readonly用于属性</p>
</li>
<li><p>const在运行时检查，readonly在编译时检查</p>
</li>
<li><p>使用const变量保存的数组，可以使用push，pop等方法。但是如果使用<code>ReadonlyArray&lt;number&gt;</code>声明的数组不能使用push，pop等方法。</p>
</li>
</ul>
<h2 id="8-3-枚举和常量枚举（const枚举）的区别"><a href="#8-3-枚举和常量枚举（const枚举）的区别" class="headerlink" title="8.3 枚举和常量枚举（const枚举）的区别"></a>8.3 枚举和常量枚举（const枚举）的区别</h2><ol>
<li><p>枚举会被编译时会编译成一个对象，可以被当作对象使用</p>
</li>
<li><p>const枚举会在ts编译期间被删除，避免额外的性能开销</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 普通枚举</span></span><br><span class="line"><span class="built_in">enum</span> Witcher &#123;</span><br><span class="line">  Ciri = <span class="string">&#x27;Queen&#x27;</span>,</span><br><span class="line">  Geralt = <span class="string">&#x27;Geralt of Rivia&#x27;</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getGeraltMessage</span>(<span class="params">arg: &#123;[key: <span class="built_in">string</span>]: <span class="built_in">string</span>&#125;</span>): <span class="title">string</span> </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> arg.Geralt</span><br><span class="line">&#125;</span><br><span class="line">getGeraltMessage(Witcher) <span class="comment">// Geralt of Rivia</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// const枚举</span></span><br><span class="line"><span class="keyword">const</span> <span class="built_in">enum</span> Witcher &#123;</span><br><span class="line">  Ciri = <span class="string">&#x27;Queen&#x27;</span>,</span><br><span class="line">  Geralt = <span class="string">&#x27;Geralt of Rivia&#x27;</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> witchers: Witcher[] = [Witcher.Ciri, Witcher.Geralt]</span><br><span class="line"><span class="comment">// 编译后</span></span><br><span class="line"><span class="comment">// const witchers = [&#x27;Queen&#x27;, &#x27;Geralt of Rivia&#x27;</span></span><br><span class="line"></span><br></pre></td></tr></table></figure></li>
</ol>
<h2 id="8-4-ts中interface可以给Function-Array-Class做声明吗？"><a href="#8-4-ts中interface可以给Function-Array-Class做声明吗？" class="headerlink" title="8.4 ts中interface可以给Function/Array/Class做声明吗？"></a>8.4 ts中interface可以给Function/Array/Class做声明吗？</h2><p>   可以的</p>
<h2 id="8-5-ts中的this和js中的this有什么差异？"><a href="#8-5-ts中的this和js中的this有什么差异？" class="headerlink" title="8.5 ts中的this和js中的this有什么差异？"></a>8.5 ts中的this和js中的this有什么差异？</h2><h2 id="8-6-ts中如何枚举联合类型的key"><a href="#8-6-ts中如何枚举联合类型的key" class="headerlink" title="8.6 ts中如何枚举联合类型的key?"></a>8.6 ts中如何枚举联合类型的key?</h2>   <figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> Name = &#123; <span class="attr">name</span>: <span class="built_in">string</span> &#125;</span><br><span class="line"><span class="keyword">type</span> Age = &#123; <span class="attr">age</span>: <span class="built_in">number</span> &#125;</span><br><span class="line"><span class="keyword">type</span> Union = Name | Age</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> UnionKey&lt;P&gt; = P <span class="keyword">extends</span> infer P ? keyof P : <span class="built_in">never</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> T = UnionKey&lt;Union&gt;</span><br></pre></td></tr></table></figure>

<h2 id="8-7-ts中-、-、-、-、-等符号的含义？"><a href="#8-7-ts中-、-、-、-、-等符号的含义？" class="headerlink" title="8.7 ts中 ?.、??、!.、_、** 等符号的含义？"></a>8.7 ts中 ?.、??、!.、_、** 等符号的含义？</h2><p>   ?.  可选链</p>
<p>   ??  ?? 类似与短路或，??避免了一些意外情况0，NaN以及””,false被视为false值。只有undefind,null被视为false值。</p>
<p>   !.  在变量名后添加!，可以断言排除undefined和null类型</p>
<p>   _ , 声明该函数将被传递一个参数，但您并不关心它</p>
<p>   ** 求幂</p>
<p>   !:，待会分配这个变量，ts不要担心</p>
   <figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// ??</span></span><br><span class="line"><span class="keyword">let</span> x = foo ?? bar();</span><br><span class="line"><span class="comment">// 等价于</span></span><br><span class="line"><span class="keyword">let</span> x = foo !== <span class="literal">null</span> &amp;&amp; foo !== <span class="literal">undefined</span> ? foo : bar();</span><br><span class="line"></span><br><span class="line"><span class="comment">// !.</span></span><br><span class="line"><span class="keyword">let</span> a: <span class="built_in">string</span> | <span class="literal">null</span> | <span class="literal">undefined</span></span><br><span class="line">a.length <span class="comment">// error</span></span><br><span class="line">a!.length <span class="comment">// ok</span></span><br><span class="line"></span><br><span class="line">作者：dyhtps</span><br><span class="line">链接：https:<span class="comment">//juejin.cn/post/6988763249982308382</span></span><br><span class="line">来源：稀土掘金</span><br><span class="line">著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。</span><br></pre></td></tr></table></figure>

<h2 id="8-8-什么是抗变、双变、协变和逆变？"><a href="#8-8-什么是抗变、双变、协变和逆变？" class="headerlink" title="8.8 什么是抗变、双变、协变和逆变？"></a>8.8 什么是抗变、双变、协变和逆变？</h2><p>   Covariant 协变，TS对象兼容性是协变，父类 &lt;= 子类，是可以的。子类 &lt;= 父类，错误。</p>
<p>   Contravariant 逆变，禁用<code>strictFunctionTypes</code>编译，函数参数类型是逆变的，父类 &lt;= 子类，是错误。子类 &lt;= 父类，是可以的。</p>
<p>   Bivariant 双向协变，函数参数的类型默认是双向协变的。父类 &lt;= 子类，是可以的。子类 &lt;= 父类，是可以的。</p>
<h2 id="8-9-ts中同名的interface或者同名的interface和class可以合并吗？"><a href="#8-9-ts中同名的interface或者同名的interface和class可以合并吗？" class="headerlink" title="8.9 ts中同名的interface或者同名的interface和class可以合并吗？"></a>8.9 ts中同名的interface或者同名的interface和class可以合并吗？</h2><pre><code>  1. interface会合并
  2. class不可以合并
</code></pre>
<h2 id="8-10-如何使ts项目引入并识别编译为js的npm库包？"><a href="#8-10-如何使ts项目引入并识别编译为js的npm库包？" class="headerlink" title="8.10 如何使ts项目引入并识别编译为js的npm库包？"></a>8.10 如何使ts项目引入并识别编译为js的npm库包？</h2><pre><code>  1. `npm install @types/xxxx`
  2. 自己添加描述文件
</code></pre>
<h2 id="8-11-ts如何自动生成库包的声明文件？"><a href="#8-11-ts如何自动生成库包的声明文件？" class="headerlink" title="8.11 ts如何自动生成库包的声明文件？"></a>8.11 ts如何自动生成库包的声明文件？</h2><p>   可以配置<code>tsconfig.json</code>文件中的<code>declaration</code>和<code>outDir</code></p>
<pre><code>  1. declaration: true, 将会自动生成声明文件
  2. outDir: &#39;&#39;, 指定目录
</code></pre>
<h2 id="8-12-什么是泛型"><a href="#8-12-什么是泛型" class="headerlink" title="8.12 什么是泛型"></a>8.12 什么是泛型</h2><p>   泛型用来来创建可重用的组件，一个组件可以支持多种类型的数据。这样用户就可以以自己的数据类型来使用组件。<strong>简单的说，“泛型就是把类型当成参数”。</strong></p>
<h2 id="8-13-，-readonly-是什么含义"><a href="#8-13-，-readonly-是什么含义" class="headerlink" title="8.13 -?，-readonly 是什么含义"></a>8.13 -?，-readonly 是什么含义</h2><p>   用于删除修饰符</p>
   <figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> A = &#123;</span><br><span class="line">    <span class="attr">a</span>: <span class="built_in">string</span>;</span><br><span class="line">    b: <span class="built_in">number</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> B = &#123;</span><br><span class="line">    [K <span class="keyword">in</span> keyof A]?: A[K]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> C = &#123;</span><br><span class="line">    [K <span class="keyword">in</span> keyof B]-?: B[K]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> D = &#123;</span><br><span class="line">    <span class="keyword">readonly</span> [K <span class="keyword">in</span> keyof A]: A[K]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> E = &#123;</span><br><span class="line">    -<span class="keyword">readonly</span> [K <span class="keyword">in</span> keyof A]: A[K]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">作者：dyhtps</span><br><span class="line">链接：https:<span class="comment">//juejin.cn/post/6988763249982308382</span></span><br><span class="line">来源：稀土掘金</span><br><span class="line">著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。</span><br></pre></td></tr></table></figure>

<h2 id="8-14-TS是基于结构类型兼容"><a href="#8-14-TS是基于结构类型兼容" class="headerlink" title="8.14 TS是基于结构类型兼容"></a>8.14 TS是基于结构类型兼容</h2><p>   typescript的类型兼容是基于结构的，不是基于名义的。下面的代码在ts中是完全可以的，但在java等基于名义的语言则会抛错。</p>
   <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">interface Named &#123; name: string &#125;</span><br><span class="line">class Person &#123;</span><br><span class="line">  name: string</span><br><span class="line">&#125;</span><br><span class="line">let p: Named</span><br><span class="line">// ok</span><br><span class="line">p = new Person()</span><br></pre></td></tr></table></figure>

<h2 id="8-15-const断言"><a href="#8-15-const断言" class="headerlink" title="8.15 const断言"></a>8.15 const断言</h2><p>   const断言，typescript会为变量添加一个自身的字面量类型</p>
<pre><code>  1. 对象字面量的属性，获得readonly的属性，成为只读属性
  2. 数组字面量成为readonly tuple只读元组
  3. 字面量类型不能被扩展（比如从hello类型到string类型）
</code></pre>
   <figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// type &#x27;&quot;hello&quot;&#x27;</span></span><br><span class="line"><span class="keyword">let</span> x = <span class="string">&quot;hello&quot;</span> <span class="keyword">as</span> <span class="keyword">const</span></span><br><span class="line"><span class="comment">// type &#x27;readonly [10, 20]&#x27;</span></span><br><span class="line"><span class="keyword">let</span> y = [<span class="number">10</span>, <span class="number">20</span>] <span class="keyword">as</span> <span class="keyword">const</span></span><br><span class="line"><span class="comment">// type &#x27;&#123; readonly text: &quot;hello&quot; &#125;&#x27;</span></span><br><span class="line"><span class="keyword">let</span> z = &#123; <span class="attr">text</span>: <span class="string">&quot;hello&quot;</span> &#125; <span class="keyword">as</span> <span class="keyword">const</span></span><br><span class="line"></span><br><span class="line">作者：dyhtps</span><br><span class="line">链接：https:<span class="comment">//juejin.cn/post/6988763249982308382</span></span><br><span class="line">来源：稀土掘金</span><br><span class="line">著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。</span><br></pre></td></tr></table></figure>

<h2 id="8-16-type-和-interface-的区别"><a href="#8-16-type-和-interface-的区别" class="headerlink" title="8.16 type 和 interface 的区别"></a>8.16 type 和 interface 的区别</h2><pre><code>  1. 类型别名可以为任何类型引入名称。例如基本类型，联合类型等
  2. 类型别名不支持继承
  3. 类型别名不会创建一个真正的名字
  4. 类型别名无法被实现(implements)，而接口可以被派生类实现
  5. 类型别名重名时编译器会抛出错误，接口重名时会产生合并
</code></pre>
<h2 id="8-17-implements-与-extends-的区别"><a href="#8-17-implements-与-extends-的区别" class="headerlink" title="8.17 implements 与 extends 的区别"></a>8.17 implements 与 extends 的区别</h2><ul>
<li>extends, 子类会继承父类的所有属性和方法。</li>
<li>implements，使用implements关键字的类将需要实现需要实现的类的所有属性和方法。</li>
</ul>
<h2 id="8-18-枚举和-object-的区别"><a href="#8-18-枚举和-object-的区别" class="headerlink" title="8.18 枚举和 object 的区别"></a>8.18 枚举和 object 的区别</h2><p>   枚举可以通过枚举的名称，获取枚举的值。也可以通过枚举的值获取枚举的名称。</p>
<p>   object只能通过key获取value</p>
<p>   数字枚举在不指定初始值的情况下，枚举值会从0开始递增。</p>
<p>   虽然在运行时，枚举是一个真实存在的对象。但是使用keyof时的行为却和普通对象不一致。必须使用keyof typeof才可以获取枚举所有属性名。</p>
<h2 id="8-19-never-void-的区别"><a href="#8-19-never-void-的区别" class="headerlink" title="8.19 never, void 的区别"></a>8.19 never, void 的区别</h2><p>   never，never表示永远不存在的类型。比如一个函数总是抛出错误，而没有返回值。或者一个函数内部有死循环，永远不会有返回值。函数的返回值就是never类型。</p>
<p>   void, 没有显示的返回值的函数返回值为void类型。如果一个变量为void类型，只能赋予undefined或者null。</p>
<h2 id="8-20-unknown-any的区别"><a href="#8-20-unknown-any的区别" class="headerlink" title="8.20 unknown, any的区别"></a>8.20 unknown, any的区别</h2><p>   unknown类型和any类型类似。与any类型不同的是。unknown类型可以接受任意类型赋值，但是unknown类型赋值给其他类型前，必须被断言</p>
<h2 id="8-21-如何在-window-扩展类型"><a href="#8-21-如何在-window-扩展类型" class="headerlink" title="8.21 如何在 window 扩展类型"></a>8.21 如何在 window 扩展类型</h2>   <figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">declare</span> <span class="built_in">global</span> &#123;</span><br><span class="line">  <span class="keyword">interface</span> Window &#123;</span><br><span class="line">    <span class="attr">myCustomFn</span>: <span class="function">() =&gt;</span> <span class="built_in">void</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="8-22-元祖越界问题"><a href="#8-22-元祖越界问题" class="headerlink" title="8.22 元祖越界问题"></a>8.22 元祖越界问题</h2>   <figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> aaa: [<span class="built_in">string</span>, <span class="built_in">number</span>] = [<span class="string">&#x27;aaa&#x27;</span>, <span class="number">5</span>];</span><br><span class="line"><span class="comment">// 添加时不会报错</span></span><br><span class="line">aaa.push(<span class="number">6</span>);</span><br><span class="line"><span class="comment">// 打印整个元祖不会报错</span></span><br><span class="line"><span class="built_in">console</span>.log(aaa); <span class="comment">// [&#x27;aaa&#x27;,5,6];</span></span><br><span class="line"><span class="comment">// 打印添加的元素时会报错</span></span><br><span class="line"><span class="built_in">console</span>.log(aaa[<span class="number">2</span>]); <span class="comment">// error</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="8-23-重写-override-vs-重载-overload"><a href="#8-23-重写-override-vs-重载-overload" class="headerlink" title="8.23 重写(override) vs 重载(overload)"></a>8.23 重写(override) vs 重载(overload)</h2><ul>
<li><p><strong>重写是指子类重写“*<em>**继承**</em>*”自父类中的方法</strong> 。虽然 TS 和JAVA 相似，但是 TS 中的继承本质上还是 JS 的“<strong>继承</strong>”机制—<strong>原型链机制</strong></p>
</li>
<li><p><strong>重载是指为同一个函数提供多个类型定义</strong></p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Animal</span> </span>&#123;</span><br><span class="line">    speak(word: <span class="built_in">string</span>): <span class="built_in">string</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&#x27;动作叫:&#x27;</span> + word;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Cat</span> <span class="keyword">extends</span> <span class="title">Animal</span> </span>&#123;</span><br><span class="line">    speak(word: <span class="built_in">string</span>): <span class="built_in">string</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&#x27;猫叫:&#x27;</span> + word;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> cat = <span class="keyword">new</span> Cat();</span><br><span class="line"><span class="built_in">console</span>.log(cat.speak(<span class="string">&#x27;hello&#x27;</span>));</span><br><span class="line"></span><br><span class="line"><span class="comment">/**--------------------------------------------**/</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">double</span>(<span class="params">val: <span class="built_in">number</span></span>): <span class="title">number</span></span></span><br><span class="line"><span class="function"><span class="function"><span class="keyword">function</span> <span class="title">double</span>(<span class="params">val: <span class="built_in">string</span></span>): <span class="title">string</span></span></span></span><br><span class="line"><span class="function"><span class="function"><span class="function"><span class="keyword">function</span> <span class="title">double</span>(<span class="params">val: <span class="built_in">any</span></span>): <span class="title">any</span> </span>&#123;</span></span></span><br><span class="line"><span class="function"><span class="function">    <span class="title">if</span> (<span class="params"><span class="keyword">typeof</span> val == <span class="string">&#x27;number&#x27;</span></span>) </span>&#123;</span></span><br><span class="line"><span class="function">        <span class="title">return</span> <span class="title">val</span> * 2</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> val + val;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> r = double(<span class="number">1</span>);</span><br><span class="line"><span class="built_in">console</span>.log(r);</span><br><span class="line"></span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="8-24-ts常见问题"><a href="#8-24-ts常见问题" class="headerlink" title="8.24 ts常见问题"></a>8.24 ts常见问题</h2><pre><code> https://juejin.cn/post/6929038446837104647
</code></pre>
<h1 id="九、微信小程序"><a href="#九、微信小程序" class="headerlink" title="九、微信小程序"></a>九、微信小程序</h1><h2 id="9-1-小程序的双向绑定和vue哪里不一样"><a href="#9-1-小程序的双向绑定和vue哪里不一样" class="headerlink" title="9.1 小程序的双向绑定和vue哪里不一样?"></a>9.1 小程序的双向绑定和vue哪里不一样?</h2><p>小程序直接 this.data 的属性是不可以同步到视图的，必须调用：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">this.setData(&#123;</span><br><span class="line">    // 这里设置</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<h2 id="9-2小程序页面间有哪些传递数据的方法"><a href="#9-2小程序页面间有哪些传递数据的方法" class="headerlink" title="9.2小程序页面间有哪些传递数据的方法?"></a>9.2小程序页面间有哪些传递数据的方法?</h2><ul>
<li><p><strong>使用全局变量实现数据传递</strong></p>
</li>
<li><p><strong>使用 wx.navigateTo 与 wx.redirectTo 的时候，可以将部分数据放在 url 里面，并在新页面 onLoad 的时候初始化</strong></p>
</li>
<li><p><strong>使用本地缓存</strong></p>
<h2 id="9-3-小程序页面的生命周期函数-及其App生命周期函数"><a href="#9-3-小程序页面的生命周期函数-及其App生命周期函数" class="headerlink" title="9.3 小程序页面的生命周期函数  及其App生命周期函数"></a>9.3 小程序页面的生命周期函数  及其App生命周期函数</h2></li>
</ul>
<p><strong>页面生命周期：</strong></p>
<p>onLoad 页面加载时触发。一个页面只会调用一次，可以在 onLoad 的参数中获取打开当前页面路径中的参数</p>
<p>onShow() 页面显示/切入前台时触发</p>
<p>onReady() 页面初次渲染完成时触发。一个页面只会调用一次，代表页面已经准备妥当，可以和视图层进行交互</p>
<p>onHide() 页面隐藏/切入后台时触发。 如 navigateTo 或底部 tab 切换到其他页面，小程序切入后台等</p>
<p>onUnload() 页面卸载时触发。如 redirectTo 或 navigateBack 到其他页面时</p>
<p><strong>APP生命周期:</strong></p>
<ul>
<li>onLaunch()  监听小程序初始化 当小程序初始化完成时，会触发 onLaunch（全局只触发一次）</li>
<li>onShow()    监听小程序显示 当小程序启动，或从后台进入前台显示，会触发 onShow</li>
<li>onHide()     监听小程序隐藏 当小程序从前台进入后台，会触发 onHide</li>
<li>onError()     错误监听函数 当小程序发生脚本错误，或者 api 调用失败时，会触发 onError 并带上错误信息</li>
</ul>
<h2 id="9-4-微信小程序的优劣势"><a href="#9-4-微信小程序的优劣势" class="headerlink" title="9.4 微信小程序的优劣势"></a>9.4 微信小程序的优劣势</h2><p><strong>优势</strong></p>
<ul>
<li>即用即走，不用安装，省流量，省安装时间，不占用桌面</li>
<li>依托微信流量，天生推广传播优势</li>
<li>开发成本比 App 低</li>
</ul>
<p><strong>缺点</strong></p>
<ul>
<li>用户留存，即用即走是优势，也存在一些问题</li>
<li>入口相对传统 App 要深很多</li>
<li>限制较多,页面大小不能超过2M。不能打开超过10个层级的页面</li>
</ul>
<h2 id="9-5-如何实现下拉刷新"><a href="#9-5-如何实现下拉刷新" class="headerlink" title="9.5 如何实现下拉刷新"></a>9.5 <strong>如何实现下拉刷新</strong></h2><p>首先在全局 config 中的 window 配置 enablePullDownRefresh<br> 在 Page 中定义 onPullDownRefresh 钩子函数,到达下拉刷新条件后，该钩子函数执行，发起请求方法<br> 请求返回后，调用 wx.stopPullDownRefresh 停止下拉刷新</p>
<h2 id="9-6-bindtap和catchtap的区别是什么"><a href="#9-6-bindtap和catchtap的区别是什么" class="headerlink" title="9.6 bindtap和catchtap的区别是什么?"></a>9.6 bindtap和catchtap的区别是什么?</h2><p><strong>相同点</strong>：首先他们都是作为点击事件函数，就是点击时触发。在这个作用上他们是一样的，可以不做区分<br><strong>不同点</strong>：他们的不同点主要是bindtap是不会阻止冒泡事件的，catchtap是阻止冒泡的</p>
<h2 id="9-7-简述下-wx-navigateTo-wx-redirectTo-wx-switchTab-wx-navigateBack-wx-reLaunch-的区别"><a href="#9-7-简述下-wx-navigateTo-wx-redirectTo-wx-switchTab-wx-navigateBack-wx-reLaunch-的区别" class="headerlink" title="9.7 简述下 wx.navigateTo(), wx.redirectTo(), wx.switchTab(), wx.navigateBack(), wx.reLaunch()的区别?"></a>9.7 简述下 wx.navigateTo(), wx.redirectTo(), wx.switchTab(), wx.navigateBack(), wx.reLaunch()的区别?</h2><p>wx.navigateTo()：保留当前页面，跳转到应用内的某个页面。但是不能跳到 tabbar 页面 wx.redirectTo()：关闭当前页面，跳转到新的页面（类似重定向）。但是不允许跳转到 tabbar 页面<br> wx.switchTab()：跳转到 tabBar 页面，并关闭其他所有非 tabBar 页面<br> wx.navigateBack():关闭当前页面，返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈，决定需要返回几层<br> wx.reLaunch()：关闭所有页面，打开到应用内的某个页面</p>
<h2 id="9-8-登录流程？"><a href="#9-8-登录流程？" class="headerlink" title="9.8 登录流程？"></a>9.8 <strong>登录流程？</strong></h2><p>登录流程是调wx.login获取code传给后台服务器获取微信用户唯一标识openid及本次登录的会话密钥（session_key、token）等）。拿到开发者服务器传回来的会话密钥（session_key、token）之后，前端要保存wx.setStorageSync(‘sessionKey’, ‘value’)或者wx.setStorageSync(‘token’, ‘value’)</p>
<p>持久登录状态：session或者token信息存放在cookie或者header的Authorization中以请求头的方式带回给服务端，放到request.js里的wx.request的header里。</p>
<h2 id="9-9-小程序父子组件之间的传参？"><a href="#9-9-小程序父子组件之间的传参？" class="headerlink" title="9.9 小程序父子组件之间的传参？"></a>9.9 小程序父子组件之间的传参？</h2><p>父向子: props</p>
<p>子向父: triggerEvent</p>
<h2 id="9-10-哪些方法可以用来提高微信小程序的应用速度？"><a href="#9-10-哪些方法可以用来提高微信小程序的应用速度？" class="headerlink" title="9.10 哪些方法可以用来提高微信小程序的应用速度？"></a>9.10 哪些方法可以用来提高微信小程序的应用速度？</h2><p>1、提高页面加载速度</p>
<p>2、用户行为预测</p>
<p>3、减少默认 <code>data</code> 的大小</p>
<p>4、组件化方案</p>
<p>5、分包</p>
<h2 id="9-11-小程序支付的流程？"><a href="#9-11-小程序支付的流程？" class="headerlink" title="9.11 小程序支付的流程？"></a>9.11 小程序支付的流程？</h2><ul>
<li><ol>
<li> 打开电商小程序，搜索浏览到某雕肥皂，点击查看详情后，发现大小、丝滑程度都很合适，点击直接下单</li>
</ol>
</li>
<li><ol start="2">
<li> 如果用户没有登录，则跳转登录页面或者弹出登录窗口，需要点击一键登录，登录流程过程跳转到之前的下单页面</li>
</ol>
</li>
<li><ol start="3">
<li>登录完成后需要将小明购买的商品Id，商品数量，以及小明这个用户的Token传送到服务器，进行创建订单</li>
</ol>
</li>
<li><ol start="4">
<li>服务器在接收到商品Id、商品数量、openId后，生成服务期订单数据，同时经过一定的签名算法，向微信支付发送请求，获取预付单信息(prepay_id)，同时将获取的数据再次进行相应规则的签名，向小程序端响应必要的信息(必须字段信息将在下文进行详细说明)</li>
</ol>
</li>
<li><p>​    5. 小程序端在获取对应的参数后，调用wx.requestPayment()发起微信支付，唤醒支付工作台，进行支付</p>
<p>具体参数:</p>
</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 时间戳  timeStamp: &#x27;&#x27;, </span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 随机字符串  nonceStr: &#x27;&#x27;, </span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 统一下单接口返回的 prepay_id 参数值  package: &#x27;&#x27;,</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 签名类型  signType: &#x27;&#x27;,  </span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 签名  paySign: &#x27;&#x27;</span></span><br></pre></td></tr></table></figure>

      

      
    </div>
    <div class="article-info article-info-index">
      
      
	<div class="article-tag tagcloud">
		<i class="icon-price-tags icon"></i>
		<ul class="article-tag-list">
			 
        		<li class="article-tag-list-item">
        			<a href="javascript:void(0)" class="js-tag article-tag-list-link color3">面试</a>
        		</li>
      		
		</ul>
	</div>

      

      
        <p class="article-more-link">
          <a class="article-more-a" href="/blog/2022/02/25/%E9%9D%A2%E8%AF%95%E5%AE%9D%E5%85%B8/">展开全文 >></a>
        </p>
      

      
      <div class="clearfix"></div>
    </div>
  </div>
</article>

<aside class="wrap-side-operation">
    <div class="mod-side-operation">
        
        <div class="jump-container" id="js-jump-container" style="display:none;">
            <a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
                <i class="icon-font icon-back"></i>
            </a>
            <div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
                <i class="icon-font icon-plane jump-plane"></i>
            </div>
        </div>
        
        
    </div>
</aside>




  
  
    <nav id="page-nav">
      <a class="extend prev" rel="prev" href="/blog/">&amp;laquo; Prev</a><a class="page-number" href="/blog/">1</a><span class="page-number current">2</span><a class="page-number" href="/blog/page/3/">3</a><a class="extend next" rel="next" href="/blog/page/3/">Next &amp;raquo;</a>
    </nav>
  


          </div>
        </div>
      </div>
      <footer id="footer">
  <div class="outer">
    <div id="footer-info">
    	<div class="footer-left">
    		&copy; 2022 John Doe
    	</div>
      	<div class="footer-right">
      		<a href="http://hexo.io/" target="_blank">Hexo</a>  Theme <a href="https://github.com/litten/hexo-theme-yilia" target="_blank">Yilia</a> by Litten
      	</div>
    </div>
  </div>
</footer>
    </div>
    <script>
	var yiliaConfig = {
		mathjax: false,
		isHome: true,
		isPost: false,
		isArchive: false,
		isTag: false,
		isCategory: false,
		open_in_new: false,
		toc_hide_index: true,
		root: "/blog/",
		innerArchive: true,
		showTags: false
	}
</script>

<script>!function(t){function n(e){if(r[e])return r[e].exports;var i=r[e]={exports:{},id:e,loaded:!1};return t[e].call(i.exports,i,i.exports,n),i.loaded=!0,i.exports}var r={};n.m=t,n.c=r,n.p="./",n(0)}([function(t,n,r){r(195),t.exports=r(191)},function(t,n,r){var e=r(3),i=r(52),o=r(27),u=r(28),c=r(53),f="prototype",a=function(t,n,r){var s,l,h,v,p=t&a.F,d=t&a.G,y=t&a.S,g=t&a.P,b=t&a.B,m=d?e:y?e[n]||(e[n]={}):(e[n]||{})[f],x=d?i:i[n]||(i[n]={}),w=x[f]||(x[f]={});d&&(r=n);for(s in r)l=!p&&m&&void 0!==m[s],h=(l?m:r)[s],v=b&&l?c(h,e):g&&"function"==typeof h?c(Function.call,h):h,m&&u(m,s,h,t&a.U),x[s]!=h&&o(x,s,v),g&&w[s]!=h&&(w[s]=h)};e.core=i,a.F=1,a.G=2,a.S=4,a.P=8,a.B=16,a.W=32,a.U=64,a.R=128,t.exports=a},function(t,n,r){var e=r(6);t.exports=function(t){if(!e(t))throw TypeError(t+" is not an object!");return t}},function(t,n){var r=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=r)},function(t,n){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,n){var r=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=r)},function(t,n){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,n,r){var e=r(126)("wks"),i=r(76),o=r(3).Symbol,u="function"==typeof o;(t.exports=function(t){return e[t]||(e[t]=u&&o[t]||(u?o:i)("Symbol."+t))}).store=e},function(t,n){var r={}.hasOwnProperty;t.exports=function(t,n){return r.call(t,n)}},function(t,n,r){var e=r(94),i=r(33);t.exports=function(t){return e(i(t))}},function(t,n,r){t.exports=!r(4)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,n,r){var e=r(2),i=r(167),o=r(50),u=Object.defineProperty;n.f=r(10)?Object.defineProperty:function(t,n,r){if(e(t),n=o(n,!0),e(r),i)try{return u(t,n,r)}catch(t){}if("get"in r||"set"in r)throw TypeError("Accessors not supported!");return"value"in r&&(t[n]=r.value),t}},function(t,n,r){t.exports=!r(18)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,n,r){var e=r(14),i=r(22);t.exports=r(12)?function(t,n,r){return e.f(t,n,i(1,r))}:function(t,n,r){return t[n]=r,t}},function(t,n,r){var e=r(20),i=r(58),o=r(42),u=Object.defineProperty;n.f=r(12)?Object.defineProperty:function(t,n,r){if(e(t),n=o(n,!0),e(r),i)try{return u(t,n,r)}catch(t){}if("get"in r||"set"in r)throw TypeError("Accessors not supported!");return"value"in r&&(t[n]=r.value),t}},function(t,n,r){var e=r(40)("wks"),i=r(23),o=r(5).Symbol,u="function"==typeof o;(t.exports=function(t){return e[t]||(e[t]=u&&o[t]||(u?o:i)("Symbol."+t))}).store=e},function(t,n,r){var e=r(67),i=Math.min;t.exports=function(t){return t>0?i(e(t),9007199254740991):0}},function(t,n,r){var e=r(46);t.exports=function(t){return Object(e(t))}},function(t,n){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,n,r){var e=r(63),i=r(34);t.exports=Object.keys||function(t){return e(t,i)}},function(t,n,r){var e=r(21);t.exports=function(t){if(!e(t))throw TypeError(t+" is not an object!");return t}},function(t,n){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,n){t.exports=function(t,n){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:n}}},function(t,n){var r=0,e=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++r+e).toString(36))}},function(t,n){var r={}.hasOwnProperty;t.exports=function(t,n){return r.call(t,n)}},function(t,n){var r=t.exports={version:"2.4.0"};"number"==typeof __e&&(__e=r)},function(t,n){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,n,r){var e=r(11),i=r(66);t.exports=r(10)?function(t,n,r){return e.f(t,n,i(1,r))}:function(t,n,r){return t[n]=r,t}},function(t,n,r){var e=r(3),i=r(27),o=r(24),u=r(76)("src"),c="toString",f=Function[c],a=(""+f).split(c);r(52).inspectSource=function(t){return f.call(t)},(t.exports=function(t,n,r,c){var f="function"==typeof r;f&&(o(r,"name")||i(r,"name",n)),t[n]!==r&&(f&&(o(r,u)||i(r,u,t[n]?""+t[n]:a.join(String(n)))),t===e?t[n]=r:c?t[n]?t[n]=r:i(t,n,r):(delete t[n],i(t,n,r)))})(Function.prototype,c,function(){return"function"==typeof this&&this[u]||f.call(this)})},function(t,n,r){var e=r(1),i=r(4),o=r(46),u=function(t,n,r,e){var i=String(o(t)),u="<"+n;return""!==r&&(u+=" "+r+'="'+String(e).replace(/"/g,"&quot;")+'"'),u+">"+i+"</"+n+">"};t.exports=function(t,n){var r={};r[t]=n(u),e(e.P+e.F*i(function(){var n=""[t]('"');return n!==n.toLowerCase()||n.split('"').length>3}),"String",r)}},function(t,n,r){var e=r(115),i=r(46);t.exports=function(t){return e(i(t))}},function(t,n,r){var e=r(116),i=r(66),o=r(30),u=r(50),c=r(24),f=r(167),a=Object.getOwnPropertyDescriptor;n.f=r(10)?a:function(t,n){if(t=o(t),n=u(n,!0),f)try{return a(t,n)}catch(t){}if(c(t,n))return i(!e.f.call(t,n),t[n])}},function(t,n,r){var e=r(24),i=r(17),o=r(145)("IE_PROTO"),u=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=i(t),e(t,o)?t[o]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?u:null}},function(t,n){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on  "+t);return t}},function(t,n){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,n){t.exports={}},function(t,n){t.exports=!0},function(t,n){n.f={}.propertyIsEnumerable},function(t,n,r){var e=r(14).f,i=r(8),o=r(15)("toStringTag");t.exports=function(t,n,r){t&&!i(t=r?t:t.prototype,o)&&e(t,o,{configurable:!0,value:n})}},function(t,n,r){var e=r(40)("keys"),i=r(23);t.exports=function(t){return e[t]||(e[t]=i(t))}},function(t,n,r){var e=r(5),i="__core-js_shared__",o=e[i]||(e[i]={});t.exports=function(t){return o[t]||(o[t]={})}},function(t,n){var r=Math.ceil,e=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?e:r)(t)}},function(t,n,r){var e=r(21);t.exports=function(t,n){if(!e(t))return t;var r,i;if(n&&"function"==typeof(r=t.toString)&&!e(i=r.call(t)))return i;if("function"==typeof(r=t.valueOf)&&!e(i=r.call(t)))return i;if(!n&&"function"==typeof(r=t.toString)&&!e(i=r.call(t)))return i;throw TypeError("Can't convert object to primitive value")}},function(t,n,r){var e=r(5),i=r(25),o=r(36),u=r(44),c=r(14).f;t.exports=function(t){var n=i.Symbol||(i.Symbol=o?{}:e.Symbol||{});"_"==t.charAt(0)||t in n||c(n,t,{value:u.f(t)})}},function(t,n,r){n.f=r(15)},function(t,n){var r={}.toString;t.exports=function(t){return r.call(t).slice(8,-1)}},function(t,n){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on  "+t);return t}},function(t,n,r){var e=r(4);t.exports=function(t,n){return!!t&&e(function(){n?t.call(null,function(){},1):t.call(null)})}},function(t,n,r){var e=r(53),i=r(115),o=r(17),u=r(16),c=r(203);t.exports=function(t,n){var r=1==t,f=2==t,a=3==t,s=4==t,l=6==t,h=5==t||l,v=n||c;return function(n,c,p){for(var d,y,g=o(n),b=i(g),m=e(c,p,3),x=u(b.length),w=0,S=r?v(n,x):f?v(n,0):void 0;x>w;w++)if((h||w in b)&&(d=b[w],y=m(d,w,g),t))if(r)S[w]=y;else if(y)switch(t){case 3:return!0;case 5:return d;case 6:return w;case 2:S.push(d)}else if(s)return!1;return l?-1:a||s?s:S}}},function(t,n,r){var e=r(1),i=r(52),o=r(4);t.exports=function(t,n){var r=(i.Object||{})[t]||Object[t],u={};u[t]=n(r),e(e.S+e.F*o(function(){r(1)}),"Object",u)}},function(t,n,r){var e=r(6);t.exports=function(t,n){if(!e(t))return t;var r,i;if(n&&"function"==typeof(r=t.toString)&&!e(i=r.call(t)))return i;if("function"==typeof(r=t.valueOf)&&!e(i=r.call(t)))return i;if(!n&&"function"==typeof(r=t.toString)&&!e(i=r.call(t)))return i;throw TypeError("Can't convert object to primitive value")}},function(t,n,r){var e=r(5),i=r(25),o=r(91),u=r(13),c="prototype",f=function(t,n,r){var a,s,l,h=t&f.F,v=t&f.G,p=t&f.S,d=t&f.P,y=t&f.B,g=t&f.W,b=v?i:i[n]||(i[n]={}),m=b[c],x=v?e:p?e[n]:(e[n]||{})[c];v&&(r=n);for(a in r)(s=!h&&x&&void 0!==x[a])&&a in b||(l=s?x[a]:r[a],b[a]=v&&"function"!=typeof x[a]?r[a]:y&&s?o(l,e):g&&x[a]==l?function(t){var n=function(n,r,e){if(this instanceof t){switch(arguments.length){case 0:return new t;case 1:return new t(n);case 2:return new t(n,r)}return new t(n,r,e)}return t.apply(this,arguments)};return n[c]=t[c],n}(l):d&&"function"==typeof l?o(Function.call,l):l,d&&((b.virtual||(b.virtual={}))[a]=l,t&f.R&&m&&!m[a]&&u(m,a,l)))};f.F=1,f.G=2,f.S=4,f.P=8,f.B=16,f.W=32,f.U=64,f.R=128,t.exports=f},function(t,n){var r=t.exports={version:"2.4.0"};"number"==typeof __e&&(__e=r)},function(t,n,r){var e=r(26);t.exports=function(t,n,r){if(e(t),void 0===n)return t;switch(r){case 1:return function(r){return t.call(n,r)};case 2:return function(r,e){return t.call(n,r,e)};case 3:return function(r,e,i){return t.call(n,r,e,i)}}return function(){return t.apply(n,arguments)}}},function(t,n,r){var e=r(183),i=r(1),o=r(126)("metadata"),u=o.store||(o.store=new(r(186))),c=function(t,n,r){var i=u.get(t);if(!i){if(!r)return;u.set(t,i=new e)}var o=i.get(n);if(!o){if(!r)return;i.set(n,o=new e)}return o},f=function(t,n,r){var e=c(n,r,!1);return void 0!==e&&e.has(t)},a=function(t,n,r){var e=c(n,r,!1);return void 0===e?void 0:e.get(t)},s=function(t,n,r,e){c(r,e,!0).set(t,n)},l=function(t,n){var r=c(t,n,!1),e=[];return r&&r.forEach(function(t,n){e.push(n)}),e},h=function(t){return void 0===t||"symbol"==typeof t?t:String(t)},v=function(t){i(i.S,"Reflect",t)};t.exports={store:u,map:c,has:f,get:a,set:s,keys:l,key:h,exp:v}},function(t,n,r){"use strict";if(r(10)){var e=r(69),i=r(3),o=r(4),u=r(1),c=r(127),f=r(152),a=r(53),s=r(68),l=r(66),h=r(27),v=r(73),p=r(67),d=r(16),y=r(75),g=r(50),b=r(24),m=r(180),x=r(114),w=r(6),S=r(17),_=r(137),O=r(70),E=r(32),P=r(71).f,j=r(154),F=r(76),M=r(7),A=r(48),N=r(117),T=r(146),I=r(155),k=r(80),L=r(123),R=r(74),C=r(130),D=r(160),U=r(11),W=r(31),G=U.f,B=W.f,V=i.RangeError,z=i.TypeError,q=i.Uint8Array,K="ArrayBuffer",J="Shared"+K,Y="BYTES_PER_ELEMENT",H="prototype",$=Array[H],X=f.ArrayBuffer,Q=f.DataView,Z=A(0),tt=A(2),nt=A(3),rt=A(4),et=A(5),it=A(6),ot=N(!0),ut=N(!1),ct=I.values,ft=I.keys,at=I.entries,st=$.lastIndexOf,lt=$.reduce,ht=$.reduceRight,vt=$.join,pt=$.sort,dt=$.slice,yt=$.toString,gt=$.toLocaleString,bt=M("iterator"),mt=M("toStringTag"),xt=F("typed_constructor"),wt=F("def_constructor"),St=c.CONSTR,_t=c.TYPED,Ot=c.VIEW,Et="Wrong length!",Pt=A(1,function(t,n){return Tt(T(t,t[wt]),n)}),jt=o(function(){return 1===new q(new Uint16Array([1]).buffer)[0]}),Ft=!!q&&!!q[H].set&&o(function(){new q(1).set({})}),Mt=function(t,n){if(void 0===t)throw z(Et);var r=+t,e=d(t);if(n&&!m(r,e))throw V(Et);return e},At=function(t,n){var r=p(t);if(r<0||r%n)throw V("Wrong offset!");return r},Nt=function(t){if(w(t)&&_t in t)return t;throw z(t+" is not a typed array!")},Tt=function(t,n){if(!(w(t)&&xt in t))throw z("It is not a typed array constructor!");return new t(n)},It=function(t,n){return kt(T(t,t[wt]),n)},kt=function(t,n){for(var r=0,e=n.length,i=Tt(t,e);e>r;)i[r]=n[r++];return i},Lt=function(t,n,r){G(t,n,{get:function(){return this._d[r]}})},Rt=function(t){var n,r,e,i,o,u,c=S(t),f=arguments.length,s=f>1?arguments[1]:void 0,l=void 0!==s,h=j(c);if(void 0!=h&&!_(h)){for(u=h.call(c),e=[],n=0;!(o=u.next()).done;n++)e.push(o.value);c=e}for(l&&f>2&&(s=a(s,arguments[2],2)),n=0,r=d(c.length),i=Tt(this,r);r>n;n++)i[n]=l?s(c[n],n):c[n];return i},Ct=function(){for(var t=0,n=arguments.length,r=Tt(this,n);n>t;)r[t]=arguments[t++];return r},Dt=!!q&&o(function(){gt.call(new q(1))}),Ut=function(){return gt.apply(Dt?dt.call(Nt(this)):Nt(this),arguments)},Wt={copyWithin:function(t,n){return D.call(Nt(this),t,n,arguments.length>2?arguments[2]:void 0)},every:function(t){return rt(Nt(this),t,arguments.length>1?arguments[1]:void 0)},fill:function(t){return C.apply(Nt(this),arguments)},filter:function(t){return It(this,tt(Nt(this),t,arguments.length>1?arguments[1]:void 0))},find:function(t){return et(Nt(this),t,arguments.length>1?arguments[1]:void 0)},findIndex:function(t){return it(Nt(this),t,arguments.length>1?arguments[1]:void 0)},forEach:function(t){Z(Nt(this),t,arguments.length>1?arguments[1]:void 0)},indexOf:function(t){return ut(Nt(this),t,arguments.length>1?arguments[1]:void 0)},includes:function(t){return ot(Nt(this),t,arguments.length>1?arguments[1]:void 0)},join:function(t){return vt.apply(Nt(this),arguments)},lastIndexOf:function(t){return st.apply(Nt(this),arguments)},map:function(t){return Pt(Nt(this),t,arguments.length>1?arguments[1]:void 0)},reduce:function(t){return lt.apply(Nt(this),arguments)},reduceRight:function(t){return ht.apply(Nt(this),arguments)},reverse:function(){for(var t,n=this,r=Nt(n).length,e=Math.floor(r/2),i=0;i<e;)t=n[i],n[i++]=n[--r],n[r]=t;return n},some:function(t){return nt(Nt(this),t,arguments.length>1?arguments[1]:void 0)},sort:function(t){return pt.call(Nt(this),t)},subarray:function(t,n){var r=Nt(this),e=r.length,i=y(t,e);return new(T(r,r[wt]))(r.buffer,r.byteOffset+i*r.BYTES_PER_ELEMENT,d((void 0===n?e:y(n,e))-i))}},Gt=function(t,n){return It(this,dt.call(Nt(this),t,n))},Bt=function(t){Nt(this);var n=At(arguments[1],1),r=this.length,e=S(t),i=d(e.length),o=0;if(i+n>r)throw V(Et);for(;o<i;)this[n+o]=e[o++]},Vt={entries:function(){return at.call(Nt(this))},keys:function(){return ft.call(Nt(this))},values:function(){return ct.call(Nt(this))}},zt=function(t,n){return w(t)&&t[_t]&&"symbol"!=typeof n&&n in t&&String(+n)==String(n)},qt=function(t,n){return zt(t,n=g(n,!0))?l(2,t[n]):B(t,n)},Kt=function(t,n,r){return!(zt(t,n=g(n,!0))&&w(r)&&b(r,"value"))||b(r,"get")||b(r,"set")||r.configurable||b(r,"writable")&&!r.writable||b(r,"enumerable")&&!r.enumerable?G(t,n,r):(t[n]=r.value,t)};St||(W.f=qt,U.f=Kt),u(u.S+u.F*!St,"Object",{getOwnPropertyDescriptor:qt,defineProperty:Kt}),o(function(){yt.call({})})&&(yt=gt=function(){return vt.call(this)});var Jt=v({},Wt);v(Jt,Vt),h(Jt,bt,Vt.values),v(Jt,{slice:Gt,set:Bt,constructor:function(){},toString:yt,toLocaleString:Ut}),Lt(Jt,"buffer","b"),Lt(Jt,"byteOffset","o"),Lt(Jt,"byteLength","l"),Lt(Jt,"length","e"),G(Jt,mt,{get:function(){return this[_t]}}),t.exports=function(t,n,r,f){f=!!f;var a=t+(f?"Clamped":"")+"Array",l="Uint8Array"!=a,v="get"+t,p="set"+t,y=i[a],g=y||{},b=y&&E(y),m=!y||!c.ABV,S={},_=y&&y[H],j=function(t,r){var e=t._d;return e.v[v](r*n+e.o,jt)},F=function(t,r,e){var i=t._d;f&&(e=(e=Math.round(e))<0?0:e>255?255:255&e),i.v[p](r*n+i.o,e,jt)},M=function(t,n){G(t,n,{get:function(){return j(this,n)},set:function(t){return F(this,n,t)},enumerable:!0})};m?(y=r(function(t,r,e,i){s(t,y,a,"_d");var o,u,c,f,l=0,v=0;if(w(r)){if(!(r instanceof X||(f=x(r))==K||f==J))return _t in r?kt(y,r):Rt.call(y,r);o=r,v=At(e,n);var p=r.byteLength;if(void 0===i){if(p%n)throw V(Et);if((u=p-v)<0)throw V(Et)}else if((u=d(i)*n)+v>p)throw V(Et);c=u/n}else c=Mt(r,!0),u=c*n,o=new X(u);for(h(t,"_d",{b:o,o:v,l:u,e:c,v:new Q(o)});l<c;)M(t,l++)}),_=y[H]=O(Jt),h(_,"constructor",y)):L(function(t){new y(null),new y(t)},!0)||(y=r(function(t,r,e,i){s(t,y,a);var o;return w(r)?r instanceof X||(o=x(r))==K||o==J?void 0!==i?new g(r,At(e,n),i):void 0!==e?new g(r,At(e,n)):new g(r):_t in r?kt(y,r):Rt.call(y,r):new g(Mt(r,l))}),Z(b!==Function.prototype?P(g).concat(P(b)):P(g),function(t){t in y||h(y,t,g[t])}),y[H]=_,e||(_.constructor=y));var A=_[bt],N=!!A&&("values"==A.name||void 0==A.name),T=Vt.values;h(y,xt,!0),h(_,_t,a),h(_,Ot,!0),h(_,wt,y),(f?new y(1)[mt]==a:mt in _)||G(_,mt,{get:function(){return a}}),S[a]=y,u(u.G+u.W+u.F*(y!=g),S),u(u.S,a,{BYTES_PER_ELEMENT:n,from:Rt,of:Ct}),Y in _||h(_,Y,n),u(u.P,a,Wt),R(a),u(u.P+u.F*Ft,a,{set:Bt}),u(u.P+u.F*!N,a,Vt),u(u.P+u.F*(_.toString!=yt),a,{toString:yt}),u(u.P+u.F*o(function(){new y(1).slice()}),a,{slice:Gt}),u(u.P+u.F*(o(function(){return[1,2].toLocaleString()!=new y([1,2]).toLocaleString()})||!o(function(){_.toLocaleString.call([1,2])})),a,{toLocaleString:Ut}),k[a]=N?A:T,e||N||h(_,bt,T)}}else t.exports=function(){}},function(t,n){var r={}.toString;t.exports=function(t){return r.call(t).slice(8,-1)}},function(t,n,r){var e=r(21),i=r(5).document,o=e(i)&&e(i.createElement);t.exports=function(t){return o?i.createElement(t):{}}},function(t,n,r){t.exports=!r(12)&&!r(18)(function(){return 7!=Object.defineProperty(r(57)("div"),"a",{get:function(){return 7}}).a})},function(t,n,r){"use strict";var e=r(36),i=r(51),o=r(64),u=r(13),c=r(8),f=r(35),a=r(96),s=r(38),l=r(103),h=r(15)("iterator"),v=!([].keys&&"next"in[].keys()),p="keys",d="values",y=function(){return this};t.exports=function(t,n,r,g,b,m,x){a(r,n,g);var w,S,_,O=function(t){if(!v&&t in F)return F[t];switch(t){case p:case d:return function(){return new r(this,t)}}return function(){return new r(this,t)}},E=n+" Iterator",P=b==d,j=!1,F=t.prototype,M=F[h]||F["@@iterator"]||b&&F[b],A=M||O(b),N=b?P?O("entries"):A:void 0,T="Array"==n?F.entries||M:M;if(T&&(_=l(T.call(new t)))!==Object.prototype&&(s(_,E,!0),e||c(_,h)||u(_,h,y)),P&&M&&M.name!==d&&(j=!0,A=function(){return M.call(this)}),e&&!x||!v&&!j&&F[h]||u(F,h,A),f[n]=A,f[E]=y,b)if(w={values:P?A:O(d),keys:m?A:O(p),entries:N},x)for(S in w)S in F||o(F,S,w[S]);else i(i.P+i.F*(v||j),n,w);return w}},function(t,n,r){var e=r(20),i=r(100),o=r(34),u=r(39)("IE_PROTO"),c=function(){},f="prototype",a=function(){var t,n=r(57)("iframe"),e=o.length;for(n.style.display="none",r(93).appendChild(n),n.src="javascript:",t=n.contentWindow.document,t.open(),t.write("<script>document.F=Object<\/script>"),t.close(),a=t.F;e--;)delete a[f][o[e]];return a()};t.exports=Object.create||function(t,n){var r;return null!==t?(c[f]=e(t),r=new c,c[f]=null,r[u]=t):r=a(),void 0===n?r:i(r,n)}},function(t,n,r){var e=r(63),i=r(34).concat("length","prototype");n.f=Object.getOwnPropertyNames||function(t){return e(t,i)}},function(t,n){n.f=Object.getOwnPropertySymbols},function(t,n,r){var e=r(8),i=r(9),o=r(90)(!1),u=r(39)("IE_PROTO");t.exports=function(t,n){var r,c=i(t),f=0,a=[];for(r in c)r!=u&&e(c,r)&&a.push(r);for(;n.length>f;)e(c,r=n[f++])&&(~o(a,r)||a.push(r));return a}},function(t,n,r){t.exports=r(13)},function(t,n,r){var e=r(76)("meta"),i=r(6),o=r(24),u=r(11).f,c=0,f=Object.isExtensible||function(){return!0},a=!r(4)(function(){return f(Object.preventExtensions({}))}),s=function(t){u(t,e,{value:{i:"O"+ ++c,w:{}}})},l=function(t,n){if(!i(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!o(t,e)){if(!f(t))return"F";if(!n)return"E";s(t)}return t[e].i},h=function(t,n){if(!o(t,e)){if(!f(t))return!0;if(!n)return!1;s(t)}return t[e].w},v=function(t){return a&&p.NEED&&f(t)&&!o(t,e)&&s(t),t},p=t.exports={KEY:e,NEED:!1,fastKey:l,getWeak:h,onFreeze:v}},function(t,n){t.exports=function(t,n){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:n}}},function(t,n){var r=Math.ceil,e=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?e:r)(t)}},function(t,n){t.exports=function(t,n,r,e){if(!(t instanceof n)||void 0!==e&&e in t)throw TypeError(r+": incorrect invocation!");return t}},function(t,n){t.exports=!1},function(t,n,r){var e=r(2),i=r(173),o=r(133),u=r(145)("IE_PROTO"),c=function(){},f="prototype",a=function(){var t,n=r(132)("iframe"),e=o.length;for(n.style.display="none",r(135).appendChild(n),n.src="javascript:",t=n.contentWindow.document,t.open(),t.write("<script>document.F=Object<\/script>"),t.close(),a=t.F;e--;)delete a[f][o[e]];return a()};t.exports=Object.create||function(t,n){var r;return null!==t?(c[f]=e(t),r=new c,c[f]=null,r[u]=t):r=a(),void 0===n?r:i(r,n)}},function(t,n,r){var e=r(175),i=r(133).concat("length","prototype");n.f=Object.getOwnPropertyNames||function(t){return e(t,i)}},function(t,n,r){var e=r(175),i=r(133);t.exports=Object.keys||function(t){return e(t,i)}},function(t,n,r){var e=r(28);t.exports=function(t,n,r){for(var i in n)e(t,i,n[i],r);return t}},function(t,n,r){"use strict";var e=r(3),i=r(11),o=r(10),u=r(7)("species");t.exports=function(t){var n=e[t];o&&n&&!n[u]&&i.f(n,u,{configurable:!0,get:function(){return this}})}},function(t,n,r){var e=r(67),i=Math.max,o=Math.min;t.exports=function(t,n){return t=e(t),t<0?i(t+n,0):o(t,n)}},function(t,n){var r=0,e=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++r+e).toString(36))}},function(t,n,r){var e=r(33);t.exports=function(t){return Object(e(t))}},function(t,n,r){var e=r(7)("unscopables"),i=Array.prototype;void 0==i[e]&&r(27)(i,e,{}),t.exports=function(t){i[e][t]=!0}},function(t,n,r){var e=r(53),i=r(169),o=r(137),u=r(2),c=r(16),f=r(154),a={},s={},n=t.exports=function(t,n,r,l,h){var v,p,d,y,g=h?function(){return t}:f(t),b=e(r,l,n?2:1),m=0;if("function"!=typeof g)throw TypeError(t+" is not iterable!");if(o(g)){for(v=c(t.length);v>m;m++)if((y=n?b(u(p=t[m])[0],p[1]):b(t[m]))===a||y===s)return y}else for(d=g.call(t);!(p=d.next()).done;)if((y=i(d,b,p.value,n))===a||y===s)return y};n.BREAK=a,n.RETURN=s},function(t,n){t.exports={}},function(t,n,r){var e=r(11).f,i=r(24),o=r(7)("toStringTag");t.exports=function(t,n,r){t&&!i(t=r?t:t.prototype,o)&&e(t,o,{configurable:!0,value:n})}},function(t,n,r){var e=r(1),i=r(46),o=r(4),u=r(150),c="["+u+"]",f="​",a=RegExp("^"+c+c+"*"),s=RegExp(c+c+"*$"),l=function(t,n,r){var i={},c=o(function(){return!!u[t]()||f[t]()!=f}),a=i[t]=c?n(h):u[t];r&&(i[r]=a),e(e.P+e.F*c,"String",i)},h=l.trim=function(t,n){return t=String(i(t)),1&n&&(t=t.replace(a,"")),2&n&&(t=t.replace(s,"")),t};t.exports=l},function(t,n,r){t.exports={default:r(86),__esModule:!0}},function(t,n,r){t.exports={default:r(87),__esModule:!0}},function(t,n,r){"use strict";function e(t){return t&&t.__esModule?t:{default:t}}n.__esModule=!0;var i=r(84),o=e(i),u=r(83),c=e(u),f="function"==typeof c.default&&"symbol"==typeof o.default?function(t){return typeof t}:function(t){return t&&"function"==typeof c.default&&t.constructor===c.default&&t!==c.default.prototype?"symbol":typeof t};n.default="function"==typeof c.default&&"symbol"===f(o.default)?function(t){return void 0===t?"undefined":f(t)}:function(t){return t&&"function"==typeof c.default&&t.constructor===c.default&&t!==c.default.prototype?"symbol":void 0===t?"undefined":f(t)}},function(t,n,r){r(110),r(108),r(111),r(112),t.exports=r(25).Symbol},function(t,n,r){r(109),r(113),t.exports=r(44).f("iterator")},function(t,n){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,n){t.exports=function(){}},function(t,n,r){var e=r(9),i=r(106),o=r(105);t.exports=function(t){return function(n,r,u){var c,f=e(n),a=i(f.length),s=o(u,a);if(t&&r!=r){for(;a>s;)if((c=f[s++])!=c)return!0}else for(;a>s;s++)if((t||s in f)&&f[s]===r)return t||s||0;return!t&&-1}}},function(t,n,r){var e=r(88);t.exports=function(t,n,r){if(e(t),void 0===n)return t;switch(r){case 1:return function(r){return t.call(n,r)};case 2:return function(r,e){return t.call(n,r,e)};case 3:return function(r,e,i){return t.call(n,r,e,i)}}return function(){return t.apply(n,arguments)}}},function(t,n,r){var e=r(19),i=r(62),o=r(37);t.exports=function(t){var n=e(t),r=i.f;if(r)for(var u,c=r(t),f=o.f,a=0;c.length>a;)f.call(t,u=c[a++])&&n.push(u);return n}},function(t,n,r){t.exports=r(5).document&&document.documentElement},function(t,n,r){var e=r(56);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==e(t)?t.split(""):Object(t)}},function(t,n,r){var e=r(56);t.exports=Array.isArray||function(t){return"Array"==e(t)}},function(t,n,r){"use strict";var e=r(60),i=r(22),o=r(38),u={};r(13)(u,r(15)("iterator"),function(){return this}),t.exports=function(t,n,r){t.prototype=e(u,{next:i(1,r)}),o(t,n+" Iterator")}},function(t,n){t.exports=function(t,n){return{value:n,done:!!t}}},function(t,n,r){var e=r(19),i=r(9);t.exports=function(t,n){for(var r,o=i(t),u=e(o),c=u.length,f=0;c>f;)if(o[r=u[f++]]===n)return r}},function(t,n,r){var e=r(23)("meta"),i=r(21),o=r(8),u=r(14).f,c=0,f=Object.isExtensible||function(){return!0},a=!r(18)(function(){return f(Object.preventExtensions({}))}),s=function(t){u(t,e,{value:{i:"O"+ ++c,w:{}}})},l=function(t,n){if(!i(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!o(t,e)){if(!f(t))return"F";if(!n)return"E";s(t)}return t[e].i},h=function(t,n){if(!o(t,e)){if(!f(t))return!0;if(!n)return!1;s(t)}return t[e].w},v=function(t){return a&&p.NEED&&f(t)&&!o(t,e)&&s(t),t},p=t.exports={KEY:e,NEED:!1,fastKey:l,getWeak:h,onFreeze:v}},function(t,n,r){var e=r(14),i=r(20),o=r(19);t.exports=r(12)?Object.defineProperties:function(t,n){i(t);for(var r,u=o(n),c=u.length,f=0;c>f;)e.f(t,r=u[f++],n[r]);return t}},function(t,n,r){var e=r(37),i=r(22),o=r(9),u=r(42),c=r(8),f=r(58),a=Object.getOwnPropertyDescriptor;n.f=r(12)?a:function(t,n){if(t=o(t),n=u(n,!0),f)try{return a(t,n)}catch(t){}if(c(t,n))return i(!e.f.call(t,n),t[n])}},function(t,n,r){var e=r(9),i=r(61).f,o={}.toString,u="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],c=function(t){try{return i(t)}catch(t){return u.slice()}};t.exports.f=function(t){return u&&"[object Window]"==o.call(t)?c(t):i(e(t))}},function(t,n,r){var e=r(8),i=r(77),o=r(39)("IE_PROTO"),u=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=i(t),e(t,o)?t[o]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?u:null}},function(t,n,r){var e=r(41),i=r(33);t.exports=function(t){return function(n,r){var o,u,c=String(i(n)),f=e(r),a=c.length;return f<0||f>=a?t?"":void 0:(o=c.charCodeAt(f),o<55296||o>56319||f+1===a||(u=c.charCodeAt(f+1))<56320||u>57343?t?c.charAt(f):o:t?c.slice(f,f+2):u-56320+(o-55296<<10)+65536)}}},function(t,n,r){var e=r(41),i=Math.max,o=Math.min;t.exports=function(t,n){return t=e(t),t<0?i(t+n,0):o(t,n)}},function(t,n,r){var e=r(41),i=Math.min;t.exports=function(t){return t>0?i(e(t),9007199254740991):0}},function(t,n,r){"use strict";var e=r(89),i=r(97),o=r(35),u=r(9);t.exports=r(59)(Array,"Array",function(t,n){this._t=u(t),this._i=0,this._k=n},function(){var t=this._t,n=this._k,r=this._i++;return!t||r>=t.length?(this._t=void 0,i(1)):"keys"==n?i(0,r):"values"==n?i(0,t[r]):i(0,[r,t[r]])},"values"),o.Arguments=o.Array,e("keys"),e("values"),e("entries")},function(t,n){},function(t,n,r){"use strict";var e=r(104)(!0);r(59)(String,"String",function(t){this._t=String(t),this._i=0},function(){var t,n=this._t,r=this._i;return r>=n.length?{value:void 0,done:!0}:(t=e(n,r),this._i+=t.length,{value:t,done:!1})})},function(t,n,r){"use strict";var e=r(5),i=r(8),o=r(12),u=r(51),c=r(64),f=r(99).KEY,a=r(18),s=r(40),l=r(38),h=r(23),v=r(15),p=r(44),d=r(43),y=r(98),g=r(92),b=r(95),m=r(20),x=r(9),w=r(42),S=r(22),_=r(60),O=r(102),E=r(101),P=r(14),j=r(19),F=E.f,M=P.f,A=O.f,N=e.Symbol,T=e.JSON,I=T&&T.stringify,k="prototype",L=v("_hidden"),R=v("toPrimitive"),C={}.propertyIsEnumerable,D=s("symbol-registry"),U=s("symbols"),W=s("op-symbols"),G=Object[k],B="function"==typeof N,V=e.QObject,z=!V||!V[k]||!V[k].findChild,q=o&&a(function(){return 7!=_(M({},"a",{get:function(){return M(this,"a",{value:7}).a}})).a})?function(t,n,r){var e=F(G,n);e&&delete G[n],M(t,n,r),e&&t!==G&&M(G,n,e)}:M,K=function(t){var n=U[t]=_(N[k]);return n._k=t,n},J=B&&"symbol"==typeof N.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof N},Y=function(t,n,r){return t===G&&Y(W,n,r),m(t),n=w(n,!0),m(r),i(U,n)?(r.enumerable?(i(t,L)&&t[L][n]&&(t[L][n]=!1),r=_(r,{enumerable:S(0,!1)})):(i(t,L)||M(t,L,S(1,{})),t[L][n]=!0),q(t,n,r)):M(t,n,r)},H=function(t,n){m(t);for(var r,e=g(n=x(n)),i=0,o=e.length;o>i;)Y(t,r=e[i++],n[r]);return t},$=function(t,n){return void 0===n?_(t):H(_(t),n)},X=function(t){var n=C.call(this,t=w(t,!0));return!(this===G&&i(U,t)&&!i(W,t))&&(!(n||!i(this,t)||!i(U,t)||i(this,L)&&this[L][t])||n)},Q=function(t,n){if(t=x(t),n=w(n,!0),t!==G||!i(U,n)||i(W,n)){var r=F(t,n);return!r||!i(U,n)||i(t,L)&&t[L][n]||(r.enumerable=!0),r}},Z=function(t){for(var n,r=A(x(t)),e=[],o=0;r.length>o;)i(U,n=r[o++])||n==L||n==f||e.push(n);return e},tt=function(t){for(var n,r=t===G,e=A(r?W:x(t)),o=[],u=0;e.length>u;)!i(U,n=e[u++])||r&&!i(G,n)||o.push(U[n]);return o};B||(N=function(){if(this instanceof N)throw TypeError("Symbol is not a constructor!");var t=h(arguments.length>0?arguments[0]:void 0),n=function(r){this===G&&n.call(W,r),i(this,L)&&i(this[L],t)&&(this[L][t]=!1),q(this,t,S(1,r))};return o&&z&&q(G,t,{configurable:!0,set:n}),K(t)},c(N[k],"toString",function(){return this._k}),E.f=Q,P.f=Y,r(61).f=O.f=Z,r(37).f=X,r(62).f=tt,o&&!r(36)&&c(G,"propertyIsEnumerable",X,!0),p.f=function(t){return K(v(t))}),u(u.G+u.W+u.F*!B,{Symbol:N});for(var nt="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),rt=0;nt.length>rt;)v(nt[rt++]);for(var nt=j(v.store),rt=0;nt.length>rt;)d(nt[rt++]);u(u.S+u.F*!B,"Symbol",{for:function(t){return i(D,t+="")?D[t]:D[t]=N(t)},keyFor:function(t){if(J(t))return y(D,t);throw TypeError(t+" is not a symbol!")},useSetter:function(){z=!0},useSimple:function(){z=!1}}),u(u.S+u.F*!B,"Object",{create:$,defineProperty:Y,defineProperties:H,getOwnPropertyDescriptor:Q,getOwnPropertyNames:Z,getOwnPropertySymbols:tt}),T&&u(u.S+u.F*(!B||a(function(){var t=N();return"[null]"!=I([t])||"{}"!=I({a:t})||"{}"!=I(Object(t))})),"JSON",{stringify:function(t){if(void 0!==t&&!J(t)){for(var n,r,e=[t],i=1;arguments.length>i;)e.push(arguments[i++]);return n=e[1],"function"==typeof n&&(r=n),!r&&b(n)||(n=function(t,n){if(r&&(n=r.call(this,t,n)),!J(n))return n}),e[1]=n,I.apply(T,e)}}}),N[k][R]||r(13)(N[k],R,N[k].valueOf),l(N,"Symbol"),l(Math,"Math",!0),l(e.JSON,"JSON",!0)},function(t,n,r){r(43)("asyncIterator")},function(t,n,r){r(43)("observable")},function(t,n,r){r(107);for(var e=r(5),i=r(13),o=r(35),u=r(15)("toStringTag"),c=["NodeList","DOMTokenList","MediaList","StyleSheetList","CSSRuleList"],f=0;f<5;f++){var a=c[f],s=e[a],l=s&&s.prototype;l&&!l[u]&&i(l,u,a),o[a]=o.Array}},function(t,n,r){var e=r(45),i=r(7)("toStringTag"),o="Arguments"==e(function(){return arguments}()),u=function(t,n){try{return t[n]}catch(t){}};t.exports=function(t){var n,r,c;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(r=u(n=Object(t),i))?r:o?e(n):"Object"==(c=e(n))&&"function"==typeof n.callee?"Arguments":c}},function(t,n,r){var e=r(45);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==e(t)?t.split(""):Object(t)}},function(t,n){n.f={}.propertyIsEnumerable},function(t,n,r){var e=r(30),i=r(16),o=r(75);t.exports=function(t){return function(n,r,u){var c,f=e(n),a=i(f.length),s=o(u,a);if(t&&r!=r){for(;a>s;)if((c=f[s++])!=c)return!0}else for(;a>s;s++)if((t||s in f)&&f[s]===r)return t||s||0;return!t&&-1}}},function(t,n,r){"use strict";var e=r(3),i=r(1),o=r(28),u=r(73),c=r(65),f=r(79),a=r(68),s=r(6),l=r(4),h=r(123),v=r(81),p=r(136);t.exports=function(t,n,r,d,y,g){var b=e[t],m=b,x=y?"set":"add",w=m&&m.prototype,S={},_=function(t){var n=w[t];o(w,t,"delete"==t?function(t){return!(g&&!s(t))&&n.call(this,0===t?0:t)}:"has"==t?function(t){return!(g&&!s(t))&&n.call(this,0===t?0:t)}:"get"==t?function(t){return g&&!s(t)?void 0:n.call(this,0===t?0:t)}:"add"==t?function(t){return n.call(this,0===t?0:t),this}:function(t,r){return n.call(this,0===t?0:t,r),this})};if("function"==typeof m&&(g||w.forEach&&!l(function(){(new m).entries().next()}))){var O=new m,E=O[x](g?{}:-0,1)!=O,P=l(function(){O.has(1)}),j=h(function(t){new m(t)}),F=!g&&l(function(){for(var t=new m,n=5;n--;)t[x](n,n);return!t.has(-0)});j||(m=n(function(n,r){a(n,m,t);var e=p(new b,n,m);return void 0!=r&&f(r,y,e[x],e),e}),m.prototype=w,w.constructor=m),(P||F)&&(_("delete"),_("has"),y&&_("get")),(F||E)&&_(x),g&&w.clear&&delete w.clear}else m=d.getConstructor(n,t,y,x),u(m.prototype,r),c.NEED=!0;return v(m,t),S[t]=m,i(i.G+i.W+i.F*(m!=b),S),g||d.setStrong(m,t,y),m}},function(t,n,r){"use strict";var e=r(27),i=r(28),o=r(4),u=r(46),c=r(7);t.exports=function(t,n,r){var f=c(t),a=r(u,f,""[t]),s=a[0],l=a[1];o(function(){var n={};return n[f]=function(){return 7},7!=""[t](n)})&&(i(String.prototype,t,s),e(RegExp.prototype,f,2==n?function(t,n){return l.call(t,this,n)}:function(t){return l.call(t,this)}))}
},function(t,n,r){"use strict";var e=r(2);t.exports=function(){var t=e(this),n="";return t.global&&(n+="g"),t.ignoreCase&&(n+="i"),t.multiline&&(n+="m"),t.unicode&&(n+="u"),t.sticky&&(n+="y"),n}},function(t,n){t.exports=function(t,n,r){var e=void 0===r;switch(n.length){case 0:return e?t():t.call(r);case 1:return e?t(n[0]):t.call(r,n[0]);case 2:return e?t(n[0],n[1]):t.call(r,n[0],n[1]);case 3:return e?t(n[0],n[1],n[2]):t.call(r,n[0],n[1],n[2]);case 4:return e?t(n[0],n[1],n[2],n[3]):t.call(r,n[0],n[1],n[2],n[3])}return t.apply(r,n)}},function(t,n,r){var e=r(6),i=r(45),o=r(7)("match");t.exports=function(t){var n;return e(t)&&(void 0!==(n=t[o])?!!n:"RegExp"==i(t))}},function(t,n,r){var e=r(7)("iterator"),i=!1;try{var o=[7][e]();o.return=function(){i=!0},Array.from(o,function(){throw 2})}catch(t){}t.exports=function(t,n){if(!n&&!i)return!1;var r=!1;try{var o=[7],u=o[e]();u.next=function(){return{done:r=!0}},o[e]=function(){return u},t(o)}catch(t){}return r}},function(t,n,r){t.exports=r(69)||!r(4)(function(){var t=Math.random();__defineSetter__.call(null,t,function(){}),delete r(3)[t]})},function(t,n){n.f=Object.getOwnPropertySymbols},function(t,n,r){var e=r(3),i="__core-js_shared__",o=e[i]||(e[i]={});t.exports=function(t){return o[t]||(o[t]={})}},function(t,n,r){for(var e,i=r(3),o=r(27),u=r(76),c=u("typed_array"),f=u("view"),a=!(!i.ArrayBuffer||!i.DataView),s=a,l=0,h="Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array".split(",");l<9;)(e=i[h[l++]])?(o(e.prototype,c,!0),o(e.prototype,f,!0)):s=!1;t.exports={ABV:a,CONSTR:s,TYPED:c,VIEW:f}},function(t,n){"use strict";var r={versions:function(){var t=window.navigator.userAgent;return{trident:t.indexOf("Trident")>-1,presto:t.indexOf("Presto")>-1,webKit:t.indexOf("AppleWebKit")>-1,gecko:t.indexOf("Gecko")>-1&&-1==t.indexOf("KHTML"),mobile:!!t.match(/AppleWebKit.*Mobile.*/),ios:!!t.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),android:t.indexOf("Android")>-1||t.indexOf("Linux")>-1,iPhone:t.indexOf("iPhone")>-1||t.indexOf("Mac")>-1,iPad:t.indexOf("iPad")>-1,webApp:-1==t.indexOf("Safari"),weixin:-1==t.indexOf("MicroMessenger")}}()};t.exports=r},function(t,n,r){"use strict";var e=r(85),i=function(t){return t&&t.__esModule?t:{default:t}}(e),o=function(){function t(t,n,e){return n||e?String.fromCharCode(n||e):r[t]||t}function n(t){return e[t]}var r={"&quot;":'"',"&lt;":"<","&gt;":">","&amp;":"&","&nbsp;":" "},e={};for(var u in r)e[r[u]]=u;return r["&apos;"]="'",e["'"]="&#39;",{encode:function(t){return t?(""+t).replace(/['<> "&]/g,n).replace(/\r?\n/g,"<br/>").replace(/\s/g,"&nbsp;"):""},decode:function(n){return n?(""+n).replace(/<br\s*\/?>/gi,"\n").replace(/&quot;|&lt;|&gt;|&amp;|&nbsp;|&apos;|&#(\d+);|&#(\d+)/g,t).replace(/\u00a0/g," "):""},encodeBase16:function(t){if(!t)return t;t+="";for(var n=[],r=0,e=t.length;e>r;r++)n.push(t.charCodeAt(r).toString(16).toUpperCase());return n.join("")},encodeBase16forJSON:function(t){if(!t)return t;t=t.replace(/[\u4E00-\u9FBF]/gi,function(t){return escape(t).replace("%u","\\u")});for(var n=[],r=0,e=t.length;e>r;r++)n.push(t.charCodeAt(r).toString(16).toUpperCase());return n.join("")},decodeBase16:function(t){if(!t)return t;t+="";for(var n=[],r=0,e=t.length;e>r;r+=2)n.push(String.fromCharCode("0x"+t.slice(r,r+2)));return n.join("")},encodeObject:function(t){if(t instanceof Array)for(var n=0,r=t.length;r>n;n++)t[n]=o.encodeObject(t[n]);else if("object"==(void 0===t?"undefined":(0,i.default)(t)))for(var e in t)t[e]=o.encodeObject(t[e]);else if("string"==typeof t)return o.encode(t);return t},loadScript:function(t){var n=document.createElement("script");document.getElementsByTagName("body")[0].appendChild(n),n.setAttribute("src",t)},addLoadEvent:function(t){var n=window.onload;"function"!=typeof window.onload?window.onload=t:window.onload=function(){n(),t()}}}}();t.exports=o},function(t,n,r){"use strict";var e=r(17),i=r(75),o=r(16);t.exports=function(t){for(var n=e(this),r=o(n.length),u=arguments.length,c=i(u>1?arguments[1]:void 0,r),f=u>2?arguments[2]:void 0,a=void 0===f?r:i(f,r);a>c;)n[c++]=t;return n}},function(t,n,r){"use strict";var e=r(11),i=r(66);t.exports=function(t,n,r){n in t?e.f(t,n,i(0,r)):t[n]=r}},function(t,n,r){var e=r(6),i=r(3).document,o=e(i)&&e(i.createElement);t.exports=function(t){return o?i.createElement(t):{}}},function(t,n){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,n,r){var e=r(7)("match");t.exports=function(t){var n=/./;try{"/./"[t](n)}catch(r){try{return n[e]=!1,!"/./"[t](n)}catch(t){}}return!0}},function(t,n,r){t.exports=r(3).document&&document.documentElement},function(t,n,r){var e=r(6),i=r(144).set;t.exports=function(t,n,r){var o,u=n.constructor;return u!==r&&"function"==typeof u&&(o=u.prototype)!==r.prototype&&e(o)&&i&&i(t,o),t}},function(t,n,r){var e=r(80),i=r(7)("iterator"),o=Array.prototype;t.exports=function(t){return void 0!==t&&(e.Array===t||o[i]===t)}},function(t,n,r){var e=r(45);t.exports=Array.isArray||function(t){return"Array"==e(t)}},function(t,n,r){"use strict";var e=r(70),i=r(66),o=r(81),u={};r(27)(u,r(7)("iterator"),function(){return this}),t.exports=function(t,n,r){t.prototype=e(u,{next:i(1,r)}),o(t,n+" Iterator")}},function(t,n,r){"use strict";var e=r(69),i=r(1),o=r(28),u=r(27),c=r(24),f=r(80),a=r(139),s=r(81),l=r(32),h=r(7)("iterator"),v=!([].keys&&"next"in[].keys()),p="keys",d="values",y=function(){return this};t.exports=function(t,n,r,g,b,m,x){a(r,n,g);var w,S,_,O=function(t){if(!v&&t in F)return F[t];switch(t){case p:case d:return function(){return new r(this,t)}}return function(){return new r(this,t)}},E=n+" Iterator",P=b==d,j=!1,F=t.prototype,M=F[h]||F["@@iterator"]||b&&F[b],A=M||O(b),N=b?P?O("entries"):A:void 0,T="Array"==n?F.entries||M:M;if(T&&(_=l(T.call(new t)))!==Object.prototype&&(s(_,E,!0),e||c(_,h)||u(_,h,y)),P&&M&&M.name!==d&&(j=!0,A=function(){return M.call(this)}),e&&!x||!v&&!j&&F[h]||u(F,h,A),f[n]=A,f[E]=y,b)if(w={values:P?A:O(d),keys:m?A:O(p),entries:N},x)for(S in w)S in F||o(F,S,w[S]);else i(i.P+i.F*(v||j),n,w);return w}},function(t,n){var r=Math.expm1;t.exports=!r||r(10)>22025.465794806718||r(10)<22025.465794806718||-2e-17!=r(-2e-17)?function(t){return 0==(t=+t)?t:t>-1e-6&&t<1e-6?t+t*t/2:Math.exp(t)-1}:r},function(t,n){t.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:t<0?-1:1}},function(t,n,r){var e=r(3),i=r(151).set,o=e.MutationObserver||e.WebKitMutationObserver,u=e.process,c=e.Promise,f="process"==r(45)(u);t.exports=function(){var t,n,r,a=function(){var e,i;for(f&&(e=u.domain)&&e.exit();t;){i=t.fn,t=t.next;try{i()}catch(e){throw t?r():n=void 0,e}}n=void 0,e&&e.enter()};if(f)r=function(){u.nextTick(a)};else if(o){var s=!0,l=document.createTextNode("");new o(a).observe(l,{characterData:!0}),r=function(){l.data=s=!s}}else if(c&&c.resolve){var h=c.resolve();r=function(){h.then(a)}}else r=function(){i.call(e,a)};return function(e){var i={fn:e,next:void 0};n&&(n.next=i),t||(t=i,r()),n=i}}},function(t,n,r){var e=r(6),i=r(2),o=function(t,n){if(i(t),!e(n)&&null!==n)throw TypeError(n+": can't set as prototype!")};t.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(t,n,e){try{e=r(53)(Function.call,r(31).f(Object.prototype,"__proto__").set,2),e(t,[]),n=!(t instanceof Array)}catch(t){n=!0}return function(t,r){return o(t,r),n?t.__proto__=r:e(t,r),t}}({},!1):void 0),check:o}},function(t,n,r){var e=r(126)("keys"),i=r(76);t.exports=function(t){return e[t]||(e[t]=i(t))}},function(t,n,r){var e=r(2),i=r(26),o=r(7)("species");t.exports=function(t,n){var r,u=e(t).constructor;return void 0===u||void 0==(r=e(u)[o])?n:i(r)}},function(t,n,r){var e=r(67),i=r(46);t.exports=function(t){return function(n,r){var o,u,c=String(i(n)),f=e(r),a=c.length;return f<0||f>=a?t?"":void 0:(o=c.charCodeAt(f),o<55296||o>56319||f+1===a||(u=c.charCodeAt(f+1))<56320||u>57343?t?c.charAt(f):o:t?c.slice(f,f+2):u-56320+(o-55296<<10)+65536)}}},function(t,n,r){var e=r(122),i=r(46);t.exports=function(t,n,r){if(e(n))throw TypeError("String#"+r+" doesn't accept regex!");return String(i(t))}},function(t,n,r){"use strict";var e=r(67),i=r(46);t.exports=function(t){var n=String(i(this)),r="",o=e(t);if(o<0||o==1/0)throw RangeError("Count can't be negative");for(;o>0;(o>>>=1)&&(n+=n))1&o&&(r+=n);return r}},function(t,n){t.exports="\t\n\v\f\r   ᠎             　\u2028\u2029\ufeff"},function(t,n,r){var e,i,o,u=r(53),c=r(121),f=r(135),a=r(132),s=r(3),l=s.process,h=s.setImmediate,v=s.clearImmediate,p=s.MessageChannel,d=0,y={},g="onreadystatechange",b=function(){var t=+this;if(y.hasOwnProperty(t)){var n=y[t];delete y[t],n()}},m=function(t){b.call(t.data)};h&&v||(h=function(t){for(var n=[],r=1;arguments.length>r;)n.push(arguments[r++]);return y[++d]=function(){c("function"==typeof t?t:Function(t),n)},e(d),d},v=function(t){delete y[t]},"process"==r(45)(l)?e=function(t){l.nextTick(u(b,t,1))}:p?(i=new p,o=i.port2,i.port1.onmessage=m,e=u(o.postMessage,o,1)):s.addEventListener&&"function"==typeof postMessage&&!s.importScripts?(e=function(t){s.postMessage(t+"","*")},s.addEventListener("message",m,!1)):e=g in a("script")?function(t){f.appendChild(a("script"))[g]=function(){f.removeChild(this),b.call(t)}}:function(t){setTimeout(u(b,t,1),0)}),t.exports={set:h,clear:v}},function(t,n,r){"use strict";var e=r(3),i=r(10),o=r(69),u=r(127),c=r(27),f=r(73),a=r(4),s=r(68),l=r(67),h=r(16),v=r(71).f,p=r(11).f,d=r(130),y=r(81),g="ArrayBuffer",b="DataView",m="prototype",x="Wrong length!",w="Wrong index!",S=e[g],_=e[b],O=e.Math,E=e.RangeError,P=e.Infinity,j=S,F=O.abs,M=O.pow,A=O.floor,N=O.log,T=O.LN2,I="buffer",k="byteLength",L="byteOffset",R=i?"_b":I,C=i?"_l":k,D=i?"_o":L,U=function(t,n,r){var e,i,o,u=Array(r),c=8*r-n-1,f=(1<<c)-1,a=f>>1,s=23===n?M(2,-24)-M(2,-77):0,l=0,h=t<0||0===t&&1/t<0?1:0;for(t=F(t),t!=t||t===P?(i=t!=t?1:0,e=f):(e=A(N(t)/T),t*(o=M(2,-e))<1&&(e--,o*=2),t+=e+a>=1?s/o:s*M(2,1-a),t*o>=2&&(e++,o/=2),e+a>=f?(i=0,e=f):e+a>=1?(i=(t*o-1)*M(2,n),e+=a):(i=t*M(2,a-1)*M(2,n),e=0));n>=8;u[l++]=255&i,i/=256,n-=8);for(e=e<<n|i,c+=n;c>0;u[l++]=255&e,e/=256,c-=8);return u[--l]|=128*h,u},W=function(t,n,r){var e,i=8*r-n-1,o=(1<<i)-1,u=o>>1,c=i-7,f=r-1,a=t[f--],s=127&a;for(a>>=7;c>0;s=256*s+t[f],f--,c-=8);for(e=s&(1<<-c)-1,s>>=-c,c+=n;c>0;e=256*e+t[f],f--,c-=8);if(0===s)s=1-u;else{if(s===o)return e?NaN:a?-P:P;e+=M(2,n),s-=u}return(a?-1:1)*e*M(2,s-n)},G=function(t){return t[3]<<24|t[2]<<16|t[1]<<8|t[0]},B=function(t){return[255&t]},V=function(t){return[255&t,t>>8&255]},z=function(t){return[255&t,t>>8&255,t>>16&255,t>>24&255]},q=function(t){return U(t,52,8)},K=function(t){return U(t,23,4)},J=function(t,n,r){p(t[m],n,{get:function(){return this[r]}})},Y=function(t,n,r,e){var i=+r,o=l(i);if(i!=o||o<0||o+n>t[C])throw E(w);var u=t[R]._b,c=o+t[D],f=u.slice(c,c+n);return e?f:f.reverse()},H=function(t,n,r,e,i,o){var u=+r,c=l(u);if(u!=c||c<0||c+n>t[C])throw E(w);for(var f=t[R]._b,a=c+t[D],s=e(+i),h=0;h<n;h++)f[a+h]=s[o?h:n-h-1]},$=function(t,n){s(t,S,g);var r=+n,e=h(r);if(r!=e)throw E(x);return e};if(u.ABV){if(!a(function(){new S})||!a(function(){new S(.5)})){S=function(t){return new j($(this,t))};for(var X,Q=S[m]=j[m],Z=v(j),tt=0;Z.length>tt;)(X=Z[tt++])in S||c(S,X,j[X]);o||(Q.constructor=S)}var nt=new _(new S(2)),rt=_[m].setInt8;nt.setInt8(0,2147483648),nt.setInt8(1,2147483649),!nt.getInt8(0)&&nt.getInt8(1)||f(_[m],{setInt8:function(t,n){rt.call(this,t,n<<24>>24)},setUint8:function(t,n){rt.call(this,t,n<<24>>24)}},!0)}else S=function(t){var n=$(this,t);this._b=d.call(Array(n),0),this[C]=n},_=function(t,n,r){s(this,_,b),s(t,S,b);var e=t[C],i=l(n);if(i<0||i>e)throw E("Wrong offset!");if(r=void 0===r?e-i:h(r),i+r>e)throw E(x);this[R]=t,this[D]=i,this[C]=r},i&&(J(S,k,"_l"),J(_,I,"_b"),J(_,k,"_l"),J(_,L,"_o")),f(_[m],{getInt8:function(t){return Y(this,1,t)[0]<<24>>24},getUint8:function(t){return Y(this,1,t)[0]},getInt16:function(t){var n=Y(this,2,t,arguments[1]);return(n[1]<<8|n[0])<<16>>16},getUint16:function(t){var n=Y(this,2,t,arguments[1]);return n[1]<<8|n[0]},getInt32:function(t){return G(Y(this,4,t,arguments[1]))},getUint32:function(t){return G(Y(this,4,t,arguments[1]))>>>0},getFloat32:function(t){return W(Y(this,4,t,arguments[1]),23,4)},getFloat64:function(t){return W(Y(this,8,t,arguments[1]),52,8)},setInt8:function(t,n){H(this,1,t,B,n)},setUint8:function(t,n){H(this,1,t,B,n)},setInt16:function(t,n){H(this,2,t,V,n,arguments[2])},setUint16:function(t,n){H(this,2,t,V,n,arguments[2])},setInt32:function(t,n){H(this,4,t,z,n,arguments[2])},setUint32:function(t,n){H(this,4,t,z,n,arguments[2])},setFloat32:function(t,n){H(this,4,t,K,n,arguments[2])},setFloat64:function(t,n){H(this,8,t,q,n,arguments[2])}});y(S,g),y(_,b),c(_[m],u.VIEW,!0),n[g]=S,n[b]=_},function(t,n,r){var e=r(3),i=r(52),o=r(69),u=r(182),c=r(11).f;t.exports=function(t){var n=i.Symbol||(i.Symbol=o?{}:e.Symbol||{});"_"==t.charAt(0)||t in n||c(n,t,{value:u.f(t)})}},function(t,n,r){var e=r(114),i=r(7)("iterator"),o=r(80);t.exports=r(52).getIteratorMethod=function(t){if(void 0!=t)return t[i]||t["@@iterator"]||o[e(t)]}},function(t,n,r){"use strict";var e=r(78),i=r(170),o=r(80),u=r(30);t.exports=r(140)(Array,"Array",function(t,n){this._t=u(t),this._i=0,this._k=n},function(){var t=this._t,n=this._k,r=this._i++;return!t||r>=t.length?(this._t=void 0,i(1)):"keys"==n?i(0,r):"values"==n?i(0,t[r]):i(0,[r,t[r]])},"values"),o.Arguments=o.Array,e("keys"),e("values"),e("entries")},function(t,n){function r(t,n){t.classList?t.classList.add(n):t.className+=" "+n}t.exports=r},function(t,n){function r(t,n){if(t.classList)t.classList.remove(n);else{var r=new RegExp("(^|\\b)"+n.split(" ").join("|")+"(\\b|$)","gi");t.className=t.className.replace(r," ")}}t.exports=r},function(t,n){function r(){throw new Error("setTimeout has not been defined")}function e(){throw new Error("clearTimeout has not been defined")}function i(t){if(s===setTimeout)return setTimeout(t,0);if((s===r||!s)&&setTimeout)return s=setTimeout,setTimeout(t,0);try{return s(t,0)}catch(n){try{return s.call(null,t,0)}catch(n){return s.call(this,t,0)}}}function o(t){if(l===clearTimeout)return clearTimeout(t);if((l===e||!l)&&clearTimeout)return l=clearTimeout,clearTimeout(t);try{return l(t)}catch(n){try{return l.call(null,t)}catch(n){return l.call(this,t)}}}function u(){d&&v&&(d=!1,v.length?p=v.concat(p):y=-1,p.length&&c())}function c(){if(!d){var t=i(u);d=!0;for(var n=p.length;n;){for(v=p,p=[];++y<n;)v&&v[y].run();y=-1,n=p.length}v=null,d=!1,o(t)}}function f(t,n){this.fun=t,this.array=n}function a(){}var s,l,h=t.exports={};!function(){try{s="function"==typeof setTimeout?setTimeout:r}catch(t){s=r}try{l="function"==typeof clearTimeout?clearTimeout:e}catch(t){l=e}}();var v,p=[],d=!1,y=-1;h.nextTick=function(t){var n=new Array(arguments.length-1);if(arguments.length>1)for(var r=1;r<arguments.length;r++)n[r-1]=arguments[r];p.push(new f(t,n)),1!==p.length||d||i(c)},f.prototype.run=function(){this.fun.apply(null,this.array)},h.title="browser",h.browser=!0,h.env={},h.argv=[],h.version="",h.versions={},h.on=a,h.addListener=a,h.once=a,h.off=a,h.removeListener=a,h.removeAllListeners=a,h.emit=a,h.prependListener=a,h.prependOnceListener=a,h.listeners=function(t){return[]},h.binding=function(t){throw new Error("process.binding is not supported")},h.cwd=function(){return"/"},h.chdir=function(t){throw new Error("process.chdir is not supported")},h.umask=function(){return 0}},function(t,n,r){var e=r(45);t.exports=function(t,n){if("number"!=typeof t&&"Number"!=e(t))throw TypeError(n);return+t}},function(t,n,r){"use strict";var e=r(17),i=r(75),o=r(16);t.exports=[].copyWithin||function(t,n){var r=e(this),u=o(r.length),c=i(t,u),f=i(n,u),a=arguments.length>2?arguments[2]:void 0,s=Math.min((void 0===a?u:i(a,u))-f,u-c),l=1;for(f<c&&c<f+s&&(l=-1,f+=s-1,c+=s-1);s-- >0;)f in r?r[c]=r[f]:delete r[c],c+=l,f+=l;return r}},function(t,n,r){var e=r(79);t.exports=function(t,n){var r=[];return e(t,!1,r.push,r,n),r}},function(t,n,r){var e=r(26),i=r(17),o=r(115),u=r(16);t.exports=function(t,n,r,c,f){e(n);var a=i(t),s=o(a),l=u(a.length),h=f?l-1:0,v=f?-1:1;if(r<2)for(;;){if(h in s){c=s[h],h+=v;break}if(h+=v,f?h<0:l<=h)throw TypeError("Reduce of empty array with no initial value")}for(;f?h>=0:l>h;h+=v)h in s&&(c=n(c,s[h],h,a));return c}},function(t,n,r){"use strict";var e=r(26),i=r(6),o=r(121),u=[].slice,c={},f=function(t,n,r){if(!(n in c)){for(var e=[],i=0;i<n;i++)e[i]="a["+i+"]";c[n]=Function("F,a","return new F("+e.join(",")+")")}return c[n](t,r)};t.exports=Function.bind||function(t){var n=e(this),r=u.call(arguments,1),c=function(){var e=r.concat(u.call(arguments));return this instanceof c?f(n,e.length,e):o(n,e,t)};return i(n.prototype)&&(c.prototype=n.prototype),c}},function(t,n,r){"use strict";var e=r(11).f,i=r(70),o=r(73),u=r(53),c=r(68),f=r(46),a=r(79),s=r(140),l=r(170),h=r(74),v=r(10),p=r(65).fastKey,d=v?"_s":"size",y=function(t,n){var r,e=p(n);if("F"!==e)return t._i[e];for(r=t._f;r;r=r.n)if(r.k==n)return r};t.exports={getConstructor:function(t,n,r,s){var l=t(function(t,e){c(t,l,n,"_i"),t._i=i(null),t._f=void 0,t._l=void 0,t[d]=0,void 0!=e&&a(e,r,t[s],t)});return o(l.prototype,{clear:function(){for(var t=this,n=t._i,r=t._f;r;r=r.n)r.r=!0,r.p&&(r.p=r.p.n=void 0),delete n[r.i];t._f=t._l=void 0,t[d]=0},delete:function(t){var n=this,r=y(n,t);if(r){var e=r.n,i=r.p;delete n._i[r.i],r.r=!0,i&&(i.n=e),e&&(e.p=i),n._f==r&&(n._f=e),n._l==r&&(n._l=i),n[d]--}return!!r},forEach:function(t){c(this,l,"forEach");for(var n,r=u(t,arguments.length>1?arguments[1]:void 0,3);n=n?n.n:this._f;)for(r(n.v,n.k,this);n&&n.r;)n=n.p},has:function(t){return!!y(this,t)}}),v&&e(l.prototype,"size",{get:function(){return f(this[d])}}),l},def:function(t,n,r){var e,i,o=y(t,n);return o?o.v=r:(t._l=o={i:i=p(n,!0),k:n,v:r,p:e=t._l,n:void 0,r:!1},t._f||(t._f=o),e&&(e.n=o),t[d]++,"F"!==i&&(t._i[i]=o)),t},getEntry:y,setStrong:function(t,n,r){s(t,n,function(t,n){this._t=t,this._k=n,this._l=void 0},function(){for(var t=this,n=t._k,r=t._l;r&&r.r;)r=r.p;return t._t&&(t._l=r=r?r.n:t._t._f)?"keys"==n?l(0,r.k):"values"==n?l(0,r.v):l(0,[r.k,r.v]):(t._t=void 0,l(1))},r?"entries":"values",!r,!0),h(n)}}},function(t,n,r){var e=r(114),i=r(161);t.exports=function(t){return function(){if(e(this)!=t)throw TypeError(t+"#toJSON isn't generic");return i(this)}}},function(t,n,r){"use strict";var e=r(73),i=r(65).getWeak,o=r(2),u=r(6),c=r(68),f=r(79),a=r(48),s=r(24),l=a(5),h=a(6),v=0,p=function(t){return t._l||(t._l=new d)},d=function(){this.a=[]},y=function(t,n){return l(t.a,function(t){return t[0]===n})};d.prototype={get:function(t){var n=y(this,t);if(n)return n[1]},has:function(t){return!!y(this,t)},set:function(t,n){var r=y(this,t);r?r[1]=n:this.a.push([t,n])},delete:function(t){var n=h(this.a,function(n){return n[0]===t});return~n&&this.a.splice(n,1),!!~n}},t.exports={getConstructor:function(t,n,r,o){var a=t(function(t,e){c(t,a,n,"_i"),t._i=v++,t._l=void 0,void 0!=e&&f(e,r,t[o],t)});return e(a.prototype,{delete:function(t){if(!u(t))return!1;var n=i(t);return!0===n?p(this).delete(t):n&&s(n,this._i)&&delete n[this._i]},has:function(t){if(!u(t))return!1;var n=i(t);return!0===n?p(this).has(t):n&&s(n,this._i)}}),a},def:function(t,n,r){var e=i(o(n),!0);return!0===e?p(t).set(n,r):e[t._i]=r,t},ufstore:p}},function(t,n,r){t.exports=!r(10)&&!r(4)(function(){return 7!=Object.defineProperty(r(132)("div"),"a",{get:function(){return 7}}).a})},function(t,n,r){var e=r(6),i=Math.floor;t.exports=function(t){return!e(t)&&isFinite(t)&&i(t)===t}},function(t,n,r){var e=r(2);t.exports=function(t,n,r,i){try{return i?n(e(r)[0],r[1]):n(r)}catch(n){var o=t.return;throw void 0!==o&&e(o.call(t)),n}}},function(t,n){t.exports=function(t,n){return{value:n,done:!!t}}},function(t,n){t.exports=Math.log1p||function(t){return(t=+t)>-1e-8&&t<1e-8?t-t*t/2:Math.log(1+t)}},function(t,n,r){"use strict";var e=r(72),i=r(125),o=r(116),u=r(17),c=r(115),f=Object.assign;t.exports=!f||r(4)(function(){var t={},n={},r=Symbol(),e="abcdefghijklmnopqrst";return t[r]=7,e.split("").forEach(function(t){n[t]=t}),7!=f({},t)[r]||Object.keys(f({},n)).join("")!=e})?function(t,n){for(var r=u(t),f=arguments.length,a=1,s=i.f,l=o.f;f>a;)for(var h,v=c(arguments[a++]),p=s?e(v).concat(s(v)):e(v),d=p.length,y=0;d>y;)l.call(v,h=p[y++])&&(r[h]=v[h]);return r}:f},function(t,n,r){var e=r(11),i=r(2),o=r(72);t.exports=r(10)?Object.defineProperties:function(t,n){i(t);for(var r,u=o(n),c=u.length,f=0;c>f;)e.f(t,r=u[f++],n[r]);return t}},function(t,n,r){var e=r(30),i=r(71).f,o={}.toString,u="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],c=function(t){try{return i(t)}catch(t){return u.slice()}};t.exports.f=function(t){return u&&"[object Window]"==o.call(t)?c(t):i(e(t))}},function(t,n,r){var e=r(24),i=r(30),o=r(117)(!1),u=r(145)("IE_PROTO");t.exports=function(t,n){var r,c=i(t),f=0,a=[];for(r in c)r!=u&&e(c,r)&&a.push(r);for(;n.length>f;)e(c,r=n[f++])&&(~o(a,r)||a.push(r));return a}},function(t,n,r){var e=r(72),i=r(30),o=r(116).f;t.exports=function(t){return function(n){for(var r,u=i(n),c=e(u),f=c.length,a=0,s=[];f>a;)o.call(u,r=c[a++])&&s.push(t?[r,u[r]]:u[r]);return s}}},function(t,n,r){var e=r(71),i=r(125),o=r(2),u=r(3).Reflect;t.exports=u&&u.ownKeys||function(t){var n=e.f(o(t)),r=i.f;return r?n.concat(r(t)):n}},function(t,n,r){var e=r(3).parseFloat,i=r(82).trim;t.exports=1/e(r(150)+"-0")!=-1/0?function(t){var n=i(String(t),3),r=e(n);return 0===r&&"-"==n.charAt(0)?-0:r}:e},function(t,n,r){var e=r(3).parseInt,i=r(82).trim,o=r(150),u=/^[\-+]?0[xX]/;t.exports=8!==e(o+"08")||22!==e(o+"0x16")?function(t,n){var r=i(String(t),3);return e(r,n>>>0||(u.test(r)?16:10))}:e},function(t,n){t.exports=Object.is||function(t,n){return t===n?0!==t||1/t==1/n:t!=t&&n!=n}},function(t,n,r){var e=r(16),i=r(149),o=r(46);t.exports=function(t,n,r,u){var c=String(o(t)),f=c.length,a=void 0===r?" ":String(r),s=e(n);if(s<=f||""==a)return c;var l=s-f,h=i.call(a,Math.ceil(l/a.length));return h.length>l&&(h=h.slice(0,l)),u?h+c:c+h}},function(t,n,r){n.f=r(7)},function(t,n,r){"use strict";var e=r(164);t.exports=r(118)("Map",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{get:function(t){var n=e.getEntry(this,t);return n&&n.v},set:function(t,n){return e.def(this,0===t?0:t,n)}},e,!0)},function(t,n,r){r(10)&&"g"!=/./g.flags&&r(11).f(RegExp.prototype,"flags",{configurable:!0,get:r(120)})},function(t,n,r){"use strict";var e=r(164);t.exports=r(118)("Set",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{add:function(t){return e.def(this,t=0===t?0:t,t)}},e)},function(t,n,r){"use strict";var e,i=r(48)(0),o=r(28),u=r(65),c=r(172),f=r(166),a=r(6),s=u.getWeak,l=Object.isExtensible,h=f.ufstore,v={},p=function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},d={get:function(t){if(a(t)){var n=s(t);return!0===n?h(this).get(t):n?n[this._i]:void 0}},set:function(t,n){return f.def(this,t,n)}},y=t.exports=r(118)("WeakMap",p,d,f,!0,!0);7!=(new y).set((Object.freeze||Object)(v),7).get(v)&&(e=f.getConstructor(p),c(e.prototype,d),u.NEED=!0,i(["delete","has","get","set"],function(t){var n=y.prototype,r=n[t];o(n,t,function(n,i){if(a(n)&&!l(n)){this._f||(this._f=new e);var o=this._f[t](n,i);return"set"==t?this:o}return r.call(this,n,i)})}))},,,,function(t,n){"use strict";function r(){var t=document.querySelector("#page-nav");if(t&&!document.querySelector("#page-nav .extend.prev")&&(t.innerHTML='<a class="extend prev disabled" rel="prev">&laquo; Prev</a>'+t.innerHTML),t&&!document.querySelector("#page-nav .extend.next")&&(t.innerHTML=t.innerHTML+'<a class="extend next disabled" rel="next">Next &raquo;</a>'),yiliaConfig&&yiliaConfig.open_in_new){document.querySelectorAll(".article-entry a:not(.article-more-a)").forEach(function(t){var n=t.getAttribute("target");n&&""!==n||t.setAttribute("target","_blank")})}if(yiliaConfig&&yiliaConfig.toc_hide_index){document.querySelectorAll(".toc-number").forEach(function(t){t.style.display="none"})}var n=document.querySelector("#js-aboutme");n&&0!==n.length&&(n.innerHTML=n.innerText)}t.exports={init:r}},function(t,n,r){"use strict";function e(t){return t&&t.__esModule?t:{default:t}}function i(t,n){var r=/\/|index.html/g;return t.replace(r,"")===n.replace(r,"")}function o(){for(var t=document.querySelectorAll(".js-header-menu li a"),n=window.location.pathname,r=0,e=t.length;r<e;r++){var o=t[r];i(n,o.getAttribute("href"))&&(0,h.default)(o,"active")}}function u(t){for(var n=t.offsetLeft,r=t.offsetParent;null!==r;)n+=r.offsetLeft,r=r.offsetParent;return n}function c(t){for(var n=t.offsetTop,r=t.offsetParent;null!==r;)n+=r.offsetTop,r=r.offsetParent;return n}function f(t,n,r,e,i){var o=u(t),f=c(t)-n;if(f-r<=i){var a=t.$newDom;a||(a=t.cloneNode(!0),(0,d.default)(t,a),t.$newDom=a,a.style.position="fixed",a.style.top=(r||f)+"px",a.style.left=o+"px",a.style.zIndex=e||2,a.style.width="100%",a.style.color="#fff"),a.style.visibility="visible",t.style.visibility="hidden"}else{t.style.visibility="visible";var s=t.$newDom;s&&(s.style.visibility="hidden")}}function a(){var t=document.querySelector(".js-overlay"),n=document.querySelector(".js-header-menu");f(t,document.body.scrollTop,-63,2,0),f(n,document.body.scrollTop,1,3,0)}function s(){document.querySelector("#container").addEventListener("scroll",function(t){a()}),window.addEventListener("scroll",function(t){a()}),a()}var l=r(156),h=e(l),v=r(157),p=(e(v),r(382)),d=e(p),y=r(128),g=e(y),b=r(190),m=e(b),x=r(129);(function(){g.default.versions.mobile&&window.screen.width<800&&(o(),s())})(),(0,x.addLoadEvent)(function(){m.default.init()}),t.exports={}},,,,function(t,n,r){(function(t){"use strict";function n(t,n,r){t[n]||Object[e](t,n,{writable:!0,configurable:!0,value:r})}if(r(381),r(391),r(198),t._babelPolyfill)throw new Error("only one instance of babel-polyfill is allowed");t._babelPolyfill=!0;var e="defineProperty";n(String.prototype,"padLeft","".padStart),n(String.prototype,"padRight","".padEnd),"pop,reverse,shift,keys,values,entries,indexOf,every,some,forEach,map,filter,find,findIndex,includes,join,slice,concat,push,splice,unshift,sort,lastIndexOf,reduce,reduceRight,copyWithin,fill".split(",").forEach(function(t){[][t]&&n(Array,t,Function.call.bind([][t]))})}).call(n,function(){return this}())},,,function(t,n,r){r(210),t.exports=r(52).RegExp.escape},,,,function(t,n,r){var e=r(6),i=r(138),o=r(7)("species");t.exports=function(t){var n;return i(t)&&(n=t.constructor,"function"!=typeof n||n!==Array&&!i(n.prototype)||(n=void 0),e(n)&&null===(n=n[o])&&(n=void 0)),void 0===n?Array:n}},function(t,n,r){var e=r(202);t.exports=function(t,n){return new(e(t))(n)}},function(t,n,r){"use strict";var e=r(2),i=r(50),o="number";t.exports=function(t){if("string"!==t&&t!==o&&"default"!==t)throw TypeError("Incorrect hint");return i(e(this),t!=o)}},function(t,n,r){var e=r(72),i=r(125),o=r(116);t.exports=function(t){var n=e(t),r=i.f;if(r)for(var u,c=r(t),f=o.f,a=0;c.length>a;)f.call(t,u=c[a++])&&n.push(u);return n}},function(t,n,r){var e=r(72),i=r(30);t.exports=function(t,n){for(var r,o=i(t),u=e(o),c=u.length,f=0;c>f;)if(o[r=u[f++]]===n)return r}},function(t,n,r){"use strict";var e=r(208),i=r(121),o=r(26);t.exports=function(){for(var t=o(this),n=arguments.length,r=Array(n),u=0,c=e._,f=!1;n>u;)(r[u]=arguments[u++])===c&&(f=!0);return function(){var e,o=this,u=arguments.length,a=0,s=0;if(!f&&!u)return i(t,r,o);if(e=r.slice(),f)for(;n>a;a++)e[a]===c&&(e[a]=arguments[s++]);for(;u>s;)e.push(arguments[s++]);return i(t,e,o)}}},function(t,n,r){t.exports=r(3)},function(t,n){t.exports=function(t,n){var r=n===Object(n)?function(t){return n[t]}:n;return function(n){return String(n).replace(t,r)}}},function(t,n,r){var e=r(1),i=r(209)(/[\\^$*+?.()|[\]{}]/g,"\\$&");e(e.S,"RegExp",{escape:function(t){return i(t)}})},function(t,n,r){var e=r(1);e(e.P,"Array",{copyWithin:r(160)}),r(78)("copyWithin")},function(t,n,r){"use strict";var e=r(1),i=r(48)(4);e(e.P+e.F*!r(47)([].every,!0),"Array",{every:function(t){return i(this,t,arguments[1])}})},function(t,n,r){var e=r(1);e(e.P,"Array",{fill:r(130)}),r(78)("fill")},function(t,n,r){"use strict";var e=r(1),i=r(48)(2);e(e.P+e.F*!r(47)([].filter,!0),"Array",{filter:function(t){return i(this,t,arguments[1])}})},function(t,n,r){"use strict";var e=r(1),i=r(48)(6),o="findIndex",u=!0;o in[]&&Array(1)[o](function(){u=!1}),e(e.P+e.F*u,"Array",{findIndex:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),r(78)(o)},function(t,n,r){"use strict";var e=r(1),i=r(48)(5),o="find",u=!0;o in[]&&Array(1)[o](function(){u=!1}),e(e.P+e.F*u,"Array",{find:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),r(78)(o)},function(t,n,r){"use strict";var e=r(1),i=r(48)(0),o=r(47)([].forEach,!0);e(e.P+e.F*!o,"Array",{forEach:function(t){return i(this,t,arguments[1])}})},function(t,n,r){"use strict";var e=r(53),i=r(1),o=r(17),u=r(169),c=r(137),f=r(16),a=r(131),s=r(154);i(i.S+i.F*!r(123)(function(t){Array.from(t)}),"Array",{from:function(t){var n,r,i,l,h=o(t),v="function"==typeof this?this:Array,p=arguments.length,d=p>1?arguments[1]:void 0,y=void 0!==d,g=0,b=s(h);if(y&&(d=e(d,p>2?arguments[2]:void 0,2)),void 0==b||v==Array&&c(b))for(n=f(h.length),r=new v(n);n>g;g++)a(r,g,y?d(h[g],g):h[g]);else for(l=b.call(h),r=new v;!(i=l.next()).done;g++)a(r,g,y?u(l,d,[i.value,g],!0):i.value);return r.length=g,r}})},function(t,n,r){"use strict";var e=r(1),i=r(117)(!1),o=[].indexOf,u=!!o&&1/[1].indexOf(1,-0)<0;e(e.P+e.F*(u||!r(47)(o)),"Array",{indexOf:function(t){return u?o.apply(this,arguments)||0:i(this,t,arguments[1])}})},function(t,n,r){var e=r(1);e(e.S,"Array",{isArray:r(138)})},function(t,n,r){"use strict";var e=r(1),i=r(30),o=[].join;e(e.P+e.F*(r(115)!=Object||!r(47)(o)),"Array",{join:function(t){return o.call(i(this),void 0===t?",":t)}})},function(t,n,r){"use strict";var e=r(1),i=r(30),o=r(67),u=r(16),c=[].lastIndexOf,f=!!c&&1/[1].lastIndexOf(1,-0)<0;e(e.P+e.F*(f||!r(47)(c)),"Array",{lastIndexOf:function(t){if(f)return c.apply(this,arguments)||0;var n=i(this),r=u(n.length),e=r-1;for(arguments.length>1&&(e=Math.min(e,o(arguments[1]))),e<0&&(e=r+e);e>=0;e--)if(e in n&&n[e]===t)return e||0;return-1}})},function(t,n,r){"use strict";var e=r(1),i=r(48)(1);e(e.P+e.F*!r(47)([].map,!0),"Array",{map:function(t){return i(this,t,arguments[1])}})},function(t,n,r){"use strict";var e=r(1),i=r(131);e(e.S+e.F*r(4)(function(){function t(){}return!(Array.of.call(t)instanceof t)}),"Array",{of:function(){for(var t=0,n=arguments.length,r=new("function"==typeof this?this:Array)(n);n>t;)i(r,t,arguments[t++]);return r.length=n,r}})},function(t,n,r){"use strict";var e=r(1),i=r(162);e(e.P+e.F*!r(47)([].reduceRight,!0),"Array",{reduceRight:function(t){return i(this,t,arguments.length,arguments[1],!0)}})},function(t,n,r){"use strict";var e=r(1),i=r(162);e(e.P+e.F*!r(47)([].reduce,!0),"Array",{reduce:function(t){return i(this,t,arguments.length,arguments[1],!1)}})},function(t,n,r){"use strict";var e=r(1),i=r(135),o=r(45),u=r(75),c=r(16),f=[].slice;e(e.P+e.F*r(4)(function(){i&&f.call(i)}),"Array",{slice:function(t,n){var r=c(this.length),e=o(this);if(n=void 0===n?r:n,"Array"==e)return f.call(this,t,n);for(var i=u(t,r),a=u(n,r),s=c(a-i),l=Array(s),h=0;h<s;h++)l[h]="String"==e?this.charAt(i+h):this[i+h];return l}})},function(t,n,r){"use strict";var e=r(1),i=r(48)(3);e(e.P+e.F*!r(47)([].some,!0),"Array",{some:function(t){return i(this,t,arguments[1])}})},function(t,n,r){"use strict";var e=r(1),i=r(26),o=r(17),u=r(4),c=[].sort,f=[1,2,3];e(e.P+e.F*(u(function(){f.sort(void 0)})||!u(function(){f.sort(null)})||!r(47)(c)),"Array",{sort:function(t){return void 0===t?c.call(o(this)):c.call(o(this),i(t))}})},function(t,n,r){r(74)("Array")},function(t,n,r){var e=r(1);e(e.S,"Date",{now:function(){return(new Date).getTime()}})},function(t,n,r){"use strict";var e=r(1),i=r(4),o=Date.prototype.getTime,u=function(t){return t>9?t:"0"+t};e(e.P+e.F*(i(function(){return"0385-07-25T07:06:39.999Z"!=new Date(-5e13-1).toISOString()})||!i(function(){new Date(NaN).toISOString()})),"Date",{toISOString:function(){
if(!isFinite(o.call(this)))throw RangeError("Invalid time value");var t=this,n=t.getUTCFullYear(),r=t.getUTCMilliseconds(),e=n<0?"-":n>9999?"+":"";return e+("00000"+Math.abs(n)).slice(e?-6:-4)+"-"+u(t.getUTCMonth()+1)+"-"+u(t.getUTCDate())+"T"+u(t.getUTCHours())+":"+u(t.getUTCMinutes())+":"+u(t.getUTCSeconds())+"."+(r>99?r:"0"+u(r))+"Z"}})},function(t,n,r){"use strict";var e=r(1),i=r(17),o=r(50);e(e.P+e.F*r(4)(function(){return null!==new Date(NaN).toJSON()||1!==Date.prototype.toJSON.call({toISOString:function(){return 1}})}),"Date",{toJSON:function(t){var n=i(this),r=o(n);return"number"!=typeof r||isFinite(r)?n.toISOString():null}})},function(t,n,r){var e=r(7)("toPrimitive"),i=Date.prototype;e in i||r(27)(i,e,r(204))},function(t,n,r){var e=Date.prototype,i="Invalid Date",o="toString",u=e[o],c=e.getTime;new Date(NaN)+""!=i&&r(28)(e,o,function(){var t=c.call(this);return t===t?u.call(this):i})},function(t,n,r){var e=r(1);e(e.P,"Function",{bind:r(163)})},function(t,n,r){"use strict";var e=r(6),i=r(32),o=r(7)("hasInstance"),u=Function.prototype;o in u||r(11).f(u,o,{value:function(t){if("function"!=typeof this||!e(t))return!1;if(!e(this.prototype))return t instanceof this;for(;t=i(t);)if(this.prototype===t)return!0;return!1}})},function(t,n,r){var e=r(11).f,i=r(66),o=r(24),u=Function.prototype,c="name",f=Object.isExtensible||function(){return!0};c in u||r(10)&&e(u,c,{configurable:!0,get:function(){try{var t=this,n=(""+t).match(/^\s*function ([^ (]*)/)[1];return o(t,c)||!f(t)||e(t,c,i(5,n)),n}catch(t){return""}}})},function(t,n,r){var e=r(1),i=r(171),o=Math.sqrt,u=Math.acosh;e(e.S+e.F*!(u&&710==Math.floor(u(Number.MAX_VALUE))&&u(1/0)==1/0),"Math",{acosh:function(t){return(t=+t)<1?NaN:t>94906265.62425156?Math.log(t)+Math.LN2:i(t-1+o(t-1)*o(t+1))}})},function(t,n,r){function e(t){return isFinite(t=+t)&&0!=t?t<0?-e(-t):Math.log(t+Math.sqrt(t*t+1)):t}var i=r(1),o=Math.asinh;i(i.S+i.F*!(o&&1/o(0)>0),"Math",{asinh:e})},function(t,n,r){var e=r(1),i=Math.atanh;e(e.S+e.F*!(i&&1/i(-0)<0),"Math",{atanh:function(t){return 0==(t=+t)?t:Math.log((1+t)/(1-t))/2}})},function(t,n,r){var e=r(1),i=r(142);e(e.S,"Math",{cbrt:function(t){return i(t=+t)*Math.pow(Math.abs(t),1/3)}})},function(t,n,r){var e=r(1);e(e.S,"Math",{clz32:function(t){return(t>>>=0)?31-Math.floor(Math.log(t+.5)*Math.LOG2E):32}})},function(t,n,r){var e=r(1),i=Math.exp;e(e.S,"Math",{cosh:function(t){return(i(t=+t)+i(-t))/2}})},function(t,n,r){var e=r(1),i=r(141);e(e.S+e.F*(i!=Math.expm1),"Math",{expm1:i})},function(t,n,r){var e=r(1),i=r(142),o=Math.pow,u=o(2,-52),c=o(2,-23),f=o(2,127)*(2-c),a=o(2,-126),s=function(t){return t+1/u-1/u};e(e.S,"Math",{fround:function(t){var n,r,e=Math.abs(t),o=i(t);return e<a?o*s(e/a/c)*a*c:(n=(1+c/u)*e,r=n-(n-e),r>f||r!=r?o*(1/0):o*r)}})},function(t,n,r){var e=r(1),i=Math.abs;e(e.S,"Math",{hypot:function(t,n){for(var r,e,o=0,u=0,c=arguments.length,f=0;u<c;)r=i(arguments[u++]),f<r?(e=f/r,o=o*e*e+1,f=r):r>0?(e=r/f,o+=e*e):o+=r;return f===1/0?1/0:f*Math.sqrt(o)}})},function(t,n,r){var e=r(1),i=Math.imul;e(e.S+e.F*r(4)(function(){return-5!=i(4294967295,5)||2!=i.length}),"Math",{imul:function(t,n){var r=65535,e=+t,i=+n,o=r&e,u=r&i;return 0|o*u+((r&e>>>16)*u+o*(r&i>>>16)<<16>>>0)}})},function(t,n,r){var e=r(1);e(e.S,"Math",{log10:function(t){return Math.log(t)/Math.LN10}})},function(t,n,r){var e=r(1);e(e.S,"Math",{log1p:r(171)})},function(t,n,r){var e=r(1);e(e.S,"Math",{log2:function(t){return Math.log(t)/Math.LN2}})},function(t,n,r){var e=r(1);e(e.S,"Math",{sign:r(142)})},function(t,n,r){var e=r(1),i=r(141),o=Math.exp;e(e.S+e.F*r(4)(function(){return-2e-17!=!Math.sinh(-2e-17)}),"Math",{sinh:function(t){return Math.abs(t=+t)<1?(i(t)-i(-t))/2:(o(t-1)-o(-t-1))*(Math.E/2)}})},function(t,n,r){var e=r(1),i=r(141),o=Math.exp;e(e.S,"Math",{tanh:function(t){var n=i(t=+t),r=i(-t);return n==1/0?1:r==1/0?-1:(n-r)/(o(t)+o(-t))}})},function(t,n,r){var e=r(1);e(e.S,"Math",{trunc:function(t){return(t>0?Math.floor:Math.ceil)(t)}})},function(t,n,r){"use strict";var e=r(3),i=r(24),o=r(45),u=r(136),c=r(50),f=r(4),a=r(71).f,s=r(31).f,l=r(11).f,h=r(82).trim,v="Number",p=e[v],d=p,y=p.prototype,g=o(r(70)(y))==v,b="trim"in String.prototype,m=function(t){var n=c(t,!1);if("string"==typeof n&&n.length>2){n=b?n.trim():h(n,3);var r,e,i,o=n.charCodeAt(0);if(43===o||45===o){if(88===(r=n.charCodeAt(2))||120===r)return NaN}else if(48===o){switch(n.charCodeAt(1)){case 66:case 98:e=2,i=49;break;case 79:case 111:e=8,i=55;break;default:return+n}for(var u,f=n.slice(2),a=0,s=f.length;a<s;a++)if((u=f.charCodeAt(a))<48||u>i)return NaN;return parseInt(f,e)}}return+n};if(!p(" 0o1")||!p("0b1")||p("+0x1")){p=function(t){var n=arguments.length<1?0:t,r=this;return r instanceof p&&(g?f(function(){y.valueOf.call(r)}):o(r)!=v)?u(new d(m(n)),r,p):m(n)};for(var x,w=r(10)?a(d):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger".split(","),S=0;w.length>S;S++)i(d,x=w[S])&&!i(p,x)&&l(p,x,s(d,x));p.prototype=y,y.constructor=p,r(28)(e,v,p)}},function(t,n,r){var e=r(1);e(e.S,"Number",{EPSILON:Math.pow(2,-52)})},function(t,n,r){var e=r(1),i=r(3).isFinite;e(e.S,"Number",{isFinite:function(t){return"number"==typeof t&&i(t)}})},function(t,n,r){var e=r(1);e(e.S,"Number",{isInteger:r(168)})},function(t,n,r){var e=r(1);e(e.S,"Number",{isNaN:function(t){return t!=t}})},function(t,n,r){var e=r(1),i=r(168),o=Math.abs;e(e.S,"Number",{isSafeInteger:function(t){return i(t)&&o(t)<=9007199254740991}})},function(t,n,r){var e=r(1);e(e.S,"Number",{MAX_SAFE_INTEGER:9007199254740991})},function(t,n,r){var e=r(1);e(e.S,"Number",{MIN_SAFE_INTEGER:-9007199254740991})},function(t,n,r){var e=r(1),i=r(178);e(e.S+e.F*(Number.parseFloat!=i),"Number",{parseFloat:i})},function(t,n,r){var e=r(1),i=r(179);e(e.S+e.F*(Number.parseInt!=i),"Number",{parseInt:i})},function(t,n,r){"use strict";var e=r(1),i=r(67),o=r(159),u=r(149),c=1..toFixed,f=Math.floor,a=[0,0,0,0,0,0],s="Number.toFixed: incorrect invocation!",l="0",h=function(t,n){for(var r=-1,e=n;++r<6;)e+=t*a[r],a[r]=e%1e7,e=f(e/1e7)},v=function(t){for(var n=6,r=0;--n>=0;)r+=a[n],a[n]=f(r/t),r=r%t*1e7},p=function(){for(var t=6,n="";--t>=0;)if(""!==n||0===t||0!==a[t]){var r=String(a[t]);n=""===n?r:n+u.call(l,7-r.length)+r}return n},d=function(t,n,r){return 0===n?r:n%2==1?d(t,n-1,r*t):d(t*t,n/2,r)},y=function(t){for(var n=0,r=t;r>=4096;)n+=12,r/=4096;for(;r>=2;)n+=1,r/=2;return n};e(e.P+e.F*(!!c&&("0.000"!==8e-5.toFixed(3)||"1"!==.9.toFixed(0)||"1.25"!==1.255.toFixed(2)||"1000000000000000128"!==(0xde0b6b3a7640080).toFixed(0))||!r(4)(function(){c.call({})})),"Number",{toFixed:function(t){var n,r,e,c,f=o(this,s),a=i(t),g="",b=l;if(a<0||a>20)throw RangeError(s);if(f!=f)return"NaN";if(f<=-1e21||f>=1e21)return String(f);if(f<0&&(g="-",f=-f),f>1e-21)if(n=y(f*d(2,69,1))-69,r=n<0?f*d(2,-n,1):f/d(2,n,1),r*=4503599627370496,(n=52-n)>0){for(h(0,r),e=a;e>=7;)h(1e7,0),e-=7;for(h(d(10,e,1),0),e=n-1;e>=23;)v(1<<23),e-=23;v(1<<e),h(1,1),v(2),b=p()}else h(0,r),h(1<<-n,0),b=p()+u.call(l,a);return a>0?(c=b.length,b=g+(c<=a?"0."+u.call(l,a-c)+b:b.slice(0,c-a)+"."+b.slice(c-a))):b=g+b,b}})},function(t,n,r){"use strict";var e=r(1),i=r(4),o=r(159),u=1..toPrecision;e(e.P+e.F*(i(function(){return"1"!==u.call(1,void 0)})||!i(function(){u.call({})})),"Number",{toPrecision:function(t){var n=o(this,"Number#toPrecision: incorrect invocation!");return void 0===t?u.call(n):u.call(n,t)}})},function(t,n,r){var e=r(1);e(e.S+e.F,"Object",{assign:r(172)})},function(t,n,r){var e=r(1);e(e.S,"Object",{create:r(70)})},function(t,n,r){var e=r(1);e(e.S+e.F*!r(10),"Object",{defineProperties:r(173)})},function(t,n,r){var e=r(1);e(e.S+e.F*!r(10),"Object",{defineProperty:r(11).f})},function(t,n,r){var e=r(6),i=r(65).onFreeze;r(49)("freeze",function(t){return function(n){return t&&e(n)?t(i(n)):n}})},function(t,n,r){var e=r(30),i=r(31).f;r(49)("getOwnPropertyDescriptor",function(){return function(t,n){return i(e(t),n)}})},function(t,n,r){r(49)("getOwnPropertyNames",function(){return r(174).f})},function(t,n,r){var e=r(17),i=r(32);r(49)("getPrototypeOf",function(){return function(t){return i(e(t))}})},function(t,n,r){var e=r(6);r(49)("isExtensible",function(t){return function(n){return!!e(n)&&(!t||t(n))}})},function(t,n,r){var e=r(6);r(49)("isFrozen",function(t){return function(n){return!e(n)||!!t&&t(n)}})},function(t,n,r){var e=r(6);r(49)("isSealed",function(t){return function(n){return!e(n)||!!t&&t(n)}})},function(t,n,r){var e=r(1);e(e.S,"Object",{is:r(180)})},function(t,n,r){var e=r(17),i=r(72);r(49)("keys",function(){return function(t){return i(e(t))}})},function(t,n,r){var e=r(6),i=r(65).onFreeze;r(49)("preventExtensions",function(t){return function(n){return t&&e(n)?t(i(n)):n}})},function(t,n,r){var e=r(6),i=r(65).onFreeze;r(49)("seal",function(t){return function(n){return t&&e(n)?t(i(n)):n}})},function(t,n,r){var e=r(1);e(e.S,"Object",{setPrototypeOf:r(144).set})},function(t,n,r){"use strict";var e=r(114),i={};i[r(7)("toStringTag")]="z",i+""!="[object z]"&&r(28)(Object.prototype,"toString",function(){return"[object "+e(this)+"]"},!0)},function(t,n,r){var e=r(1),i=r(178);e(e.G+e.F*(parseFloat!=i),{parseFloat:i})},function(t,n,r){var e=r(1),i=r(179);e(e.G+e.F*(parseInt!=i),{parseInt:i})},function(t,n,r){"use strict";var e,i,o,u=r(69),c=r(3),f=r(53),a=r(114),s=r(1),l=r(6),h=r(26),v=r(68),p=r(79),d=r(146),y=r(151).set,g=r(143)(),b="Promise",m=c.TypeError,x=c.process,w=c[b],x=c.process,S="process"==a(x),_=function(){},O=!!function(){try{var t=w.resolve(1),n=(t.constructor={})[r(7)("species")]=function(t){t(_,_)};return(S||"function"==typeof PromiseRejectionEvent)&&t.then(_)instanceof n}catch(t){}}(),E=function(t,n){return t===n||t===w&&n===o},P=function(t){var n;return!(!l(t)||"function"!=typeof(n=t.then))&&n},j=function(t){return E(w,t)?new F(t):new i(t)},F=i=function(t){var n,r;this.promise=new t(function(t,e){if(void 0!==n||void 0!==r)throw m("Bad Promise constructor");n=t,r=e}),this.resolve=h(n),this.reject=h(r)},M=function(t){try{t()}catch(t){return{error:t}}},A=function(t,n){if(!t._n){t._n=!0;var r=t._c;g(function(){for(var e=t._v,i=1==t._s,o=0;r.length>o;)!function(n){var r,o,u=i?n.ok:n.fail,c=n.resolve,f=n.reject,a=n.domain;try{u?(i||(2==t._h&&I(t),t._h=1),!0===u?r=e:(a&&a.enter(),r=u(e),a&&a.exit()),r===n.promise?f(m("Promise-chain cycle")):(o=P(r))?o.call(r,c,f):c(r)):f(e)}catch(t){f(t)}}(r[o++]);t._c=[],t._n=!1,n&&!t._h&&N(t)})}},N=function(t){y.call(c,function(){var n,r,e,i=t._v;if(T(t)&&(n=M(function(){S?x.emit("unhandledRejection",i,t):(r=c.onunhandledrejection)?r({promise:t,reason:i}):(e=c.console)&&e.error&&e.error("Unhandled promise rejection",i)}),t._h=S||T(t)?2:1),t._a=void 0,n)throw n.error})},T=function(t){if(1==t._h)return!1;for(var n,r=t._a||t._c,e=0;r.length>e;)if(n=r[e++],n.fail||!T(n.promise))return!1;return!0},I=function(t){y.call(c,function(){var n;S?x.emit("rejectionHandled",t):(n=c.onrejectionhandled)&&n({promise:t,reason:t._v})})},k=function(t){var n=this;n._d||(n._d=!0,n=n._w||n,n._v=t,n._s=2,n._a||(n._a=n._c.slice()),A(n,!0))},L=function(t){var n,r=this;if(!r._d){r._d=!0,r=r._w||r;try{if(r===t)throw m("Promise can't be resolved itself");(n=P(t))?g(function(){var e={_w:r,_d:!1};try{n.call(t,f(L,e,1),f(k,e,1))}catch(t){k.call(e,t)}}):(r._v=t,r._s=1,A(r,!1))}catch(t){k.call({_w:r,_d:!1},t)}}};O||(w=function(t){v(this,w,b,"_h"),h(t),e.call(this);try{t(f(L,this,1),f(k,this,1))}catch(t){k.call(this,t)}},e=function(t){this._c=[],this._a=void 0,this._s=0,this._d=!1,this._v=void 0,this._h=0,this._n=!1},e.prototype=r(73)(w.prototype,{then:function(t,n){var r=j(d(this,w));return r.ok="function"!=typeof t||t,r.fail="function"==typeof n&&n,r.domain=S?x.domain:void 0,this._c.push(r),this._a&&this._a.push(r),this._s&&A(this,!1),r.promise},catch:function(t){return this.then(void 0,t)}}),F=function(){var t=new e;this.promise=t,this.resolve=f(L,t,1),this.reject=f(k,t,1)}),s(s.G+s.W+s.F*!O,{Promise:w}),r(81)(w,b),r(74)(b),o=r(52)[b],s(s.S+s.F*!O,b,{reject:function(t){var n=j(this);return(0,n.reject)(t),n.promise}}),s(s.S+s.F*(u||!O),b,{resolve:function(t){if(t instanceof w&&E(t.constructor,this))return t;var n=j(this);return(0,n.resolve)(t),n.promise}}),s(s.S+s.F*!(O&&r(123)(function(t){w.all(t).catch(_)})),b,{all:function(t){var n=this,r=j(n),e=r.resolve,i=r.reject,o=M(function(){var r=[],o=0,u=1;p(t,!1,function(t){var c=o++,f=!1;r.push(void 0),u++,n.resolve(t).then(function(t){f||(f=!0,r[c]=t,--u||e(r))},i)}),--u||e(r)});return o&&i(o.error),r.promise},race:function(t){var n=this,r=j(n),e=r.reject,i=M(function(){p(t,!1,function(t){n.resolve(t).then(r.resolve,e)})});return i&&e(i.error),r.promise}})},function(t,n,r){var e=r(1),i=r(26),o=r(2),u=(r(3).Reflect||{}).apply,c=Function.apply;e(e.S+e.F*!r(4)(function(){u(function(){})}),"Reflect",{apply:function(t,n,r){var e=i(t),f=o(r);return u?u(e,n,f):c.call(e,n,f)}})},function(t,n,r){var e=r(1),i=r(70),o=r(26),u=r(2),c=r(6),f=r(4),a=r(163),s=(r(3).Reflect||{}).construct,l=f(function(){function t(){}return!(s(function(){},[],t)instanceof t)}),h=!f(function(){s(function(){})});e(e.S+e.F*(l||h),"Reflect",{construct:function(t,n){o(t),u(n);var r=arguments.length<3?t:o(arguments[2]);if(h&&!l)return s(t,n,r);if(t==r){switch(n.length){case 0:return new t;case 1:return new t(n[0]);case 2:return new t(n[0],n[1]);case 3:return new t(n[0],n[1],n[2]);case 4:return new t(n[0],n[1],n[2],n[3])}var e=[null];return e.push.apply(e,n),new(a.apply(t,e))}var f=r.prototype,v=i(c(f)?f:Object.prototype),p=Function.apply.call(t,v,n);return c(p)?p:v}})},function(t,n,r){var e=r(11),i=r(1),o=r(2),u=r(50);i(i.S+i.F*r(4)(function(){Reflect.defineProperty(e.f({},1,{value:1}),1,{value:2})}),"Reflect",{defineProperty:function(t,n,r){o(t),n=u(n,!0),o(r);try{return e.f(t,n,r),!0}catch(t){return!1}}})},function(t,n,r){var e=r(1),i=r(31).f,o=r(2);e(e.S,"Reflect",{deleteProperty:function(t,n){var r=i(o(t),n);return!(r&&!r.configurable)&&delete t[n]}})},function(t,n,r){"use strict";var e=r(1),i=r(2),o=function(t){this._t=i(t),this._i=0;var n,r=this._k=[];for(n in t)r.push(n)};r(139)(o,"Object",function(){var t,n=this,r=n._k;do{if(n._i>=r.length)return{value:void 0,done:!0}}while(!((t=r[n._i++])in n._t));return{value:t,done:!1}}),e(e.S,"Reflect",{enumerate:function(t){return new o(t)}})},function(t,n,r){var e=r(31),i=r(1),o=r(2);i(i.S,"Reflect",{getOwnPropertyDescriptor:function(t,n){return e.f(o(t),n)}})},function(t,n,r){var e=r(1),i=r(32),o=r(2);e(e.S,"Reflect",{getPrototypeOf:function(t){return i(o(t))}})},function(t,n,r){function e(t,n){var r,c,s=arguments.length<3?t:arguments[2];return a(t)===s?t[n]:(r=i.f(t,n))?u(r,"value")?r.value:void 0!==r.get?r.get.call(s):void 0:f(c=o(t))?e(c,n,s):void 0}var i=r(31),o=r(32),u=r(24),c=r(1),f=r(6),a=r(2);c(c.S,"Reflect",{get:e})},function(t,n,r){var e=r(1);e(e.S,"Reflect",{has:function(t,n){return n in t}})},function(t,n,r){var e=r(1),i=r(2),o=Object.isExtensible;e(e.S,"Reflect",{isExtensible:function(t){return i(t),!o||o(t)}})},function(t,n,r){var e=r(1);e(e.S,"Reflect",{ownKeys:r(177)})},function(t,n,r){var e=r(1),i=r(2),o=Object.preventExtensions;e(e.S,"Reflect",{preventExtensions:function(t){i(t);try{return o&&o(t),!0}catch(t){return!1}}})},function(t,n,r){var e=r(1),i=r(144);i&&e(e.S,"Reflect",{setPrototypeOf:function(t,n){i.check(t,n);try{return i.set(t,n),!0}catch(t){return!1}}})},function(t,n,r){function e(t,n,r){var f,h,v=arguments.length<4?t:arguments[3],p=o.f(s(t),n);if(!p){if(l(h=u(t)))return e(h,n,r,v);p=a(0)}return c(p,"value")?!(!1===p.writable||!l(v)||(f=o.f(v,n)||a(0),f.value=r,i.f(v,n,f),0)):void 0!==p.set&&(p.set.call(v,r),!0)}var i=r(11),o=r(31),u=r(32),c=r(24),f=r(1),a=r(66),s=r(2),l=r(6);f(f.S,"Reflect",{set:e})},function(t,n,r){var e=r(3),i=r(136),o=r(11).f,u=r(71).f,c=r(122),f=r(120),a=e.RegExp,s=a,l=a.prototype,h=/a/g,v=/a/g,p=new a(h)!==h;if(r(10)&&(!p||r(4)(function(){return v[r(7)("match")]=!1,a(h)!=h||a(v)==v||"/a/i"!=a(h,"i")}))){a=function(t,n){var r=this instanceof a,e=c(t),o=void 0===n;return!r&&e&&t.constructor===a&&o?t:i(p?new s(e&&!o?t.source:t,n):s((e=t instanceof a)?t.source:t,e&&o?f.call(t):n),r?this:l,a)};for(var d=u(s),y=0;d.length>y;)!function(t){t in a||o(a,t,{configurable:!0,get:function(){return s[t]},set:function(n){s[t]=n}})}(d[y++]);l.constructor=a,a.prototype=l,r(28)(e,"RegExp",a)}r(74)("RegExp")},function(t,n,r){r(119)("match",1,function(t,n,r){return[function(r){"use strict";var e=t(this),i=void 0==r?void 0:r[n];return void 0!==i?i.call(r,e):new RegExp(r)[n](String(e))},r]})},function(t,n,r){r(119)("replace",2,function(t,n,r){return[function(e,i){"use strict";var o=t(this),u=void 0==e?void 0:e[n];return void 0!==u?u.call(e,o,i):r.call(String(o),e,i)},r]})},function(t,n,r){r(119)("search",1,function(t,n,r){return[function(r){"use strict";var e=t(this),i=void 0==r?void 0:r[n];return void 0!==i?i.call(r,e):new RegExp(r)[n](String(e))},r]})},function(t,n,r){r(119)("split",2,function(t,n,e){"use strict";var i=r(122),o=e,u=[].push,c="split",f="length",a="lastIndex";if("c"=="abbc"[c](/(b)*/)[1]||4!="test"[c](/(?:)/,-1)[f]||2!="ab"[c](/(?:ab)*/)[f]||4!="."[c](/(.?)(.?)/)[f]||"."[c](/()()/)[f]>1||""[c](/.?/)[f]){var s=void 0===/()??/.exec("")[1];e=function(t,n){var r=String(this);if(void 0===t&&0===n)return[];if(!i(t))return o.call(r,t,n);var e,c,l,h,v,p=[],d=(t.ignoreCase?"i":"")+(t.multiline?"m":"")+(t.unicode?"u":"")+(t.sticky?"y":""),y=0,g=void 0===n?4294967295:n>>>0,b=new RegExp(t.source,d+"g");for(s||(e=new RegExp("^"+b.source+"$(?!\\s)",d));(c=b.exec(r))&&!((l=c.index+c[0][f])>y&&(p.push(r.slice(y,c.index)),!s&&c[f]>1&&c[0].replace(e,function(){for(v=1;v<arguments[f]-2;v++)void 0===arguments[v]&&(c[v]=void 0)}),c[f]>1&&c.index<r[f]&&u.apply(p,c.slice(1)),h=c[0][f],y=l,p[f]>=g));)b[a]===c.index&&b[a]++;return y===r[f]?!h&&b.test("")||p.push(""):p.push(r.slice(y)),p[f]>g?p.slice(0,g):p}}else"0"[c](void 0,0)[f]&&(e=function(t,n){return void 0===t&&0===n?[]:o.call(this,t,n)});return[function(r,i){var o=t(this),u=void 0==r?void 0:r[n];return void 0!==u?u.call(r,o,i):e.call(String(o),r,i)},e]})},function(t,n,r){"use strict";r(184);var e=r(2),i=r(120),o=r(10),u="toString",c=/./[u],f=function(t){r(28)(RegExp.prototype,u,t,!0)};r(4)(function(){return"/a/b"!=c.call({source:"a",flags:"b"})})?f(function(){var t=e(this);return"/".concat(t.source,"/","flags"in t?t.flags:!o&&t instanceof RegExp?i.call(t):void 0)}):c.name!=u&&f(function(){return c.call(this)})},function(t,n,r){"use strict";r(29)("anchor",function(t){return function(n){return t(this,"a","name",n)}})},function(t,n,r){"use strict";r(29)("big",function(t){return function(){return t(this,"big","","")}})},function(t,n,r){"use strict";r(29)("blink",function(t){return function(){return t(this,"blink","","")}})},function(t,n,r){"use strict";r(29)("bold",function(t){return function(){return t(this,"b","","")}})},function(t,n,r){"use strict";var e=r(1),i=r(147)(!1);e(e.P,"String",{codePointAt:function(t){return i(this,t)}})},function(t,n,r){"use strict";var e=r(1),i=r(16),o=r(148),u="endsWith",c=""[u];e(e.P+e.F*r(134)(u),"String",{endsWith:function(t){var n=o(this,t,u),r=arguments.length>1?arguments[1]:void 0,e=i(n.length),f=void 0===r?e:Math.min(i(r),e),a=String(t);return c?c.call(n,a,f):n.slice(f-a.length,f)===a}})},function(t,n,r){"use strict";r(29)("fixed",function(t){return function(){return t(this,"tt","","")}})},function(t,n,r){"use strict";r(29)("fontcolor",function(t){return function(n){return t(this,"font","color",n)}})},function(t,n,r){"use strict";r(29)("fontsize",function(t){return function(n){return t(this,"font","size",n)}})},function(t,n,r){var e=r(1),i=r(75),o=String.fromCharCode,u=String.fromCodePoint;e(e.S+e.F*(!!u&&1!=u.length),"String",{fromCodePoint:function(t){for(var n,r=[],e=arguments.length,u=0;e>u;){if(n=+arguments[u++],i(n,1114111)!==n)throw RangeError(n+" is not a valid code point");r.push(n<65536?o(n):o(55296+((n-=65536)>>10),n%1024+56320))}return r.join("")}})},function(t,n,r){"use strict";var e=r(1),i=r(148),o="includes";e(e.P+e.F*r(134)(o),"String",{includes:function(t){return!!~i(this,t,o).indexOf(t,arguments.length>1?arguments[1]:void 0)}})},function(t,n,r){"use strict";r(29)("italics",function(t){return function(){return t(this,"i","","")}})},function(t,n,r){"use strict";var e=r(147)(!0);r(140)(String,"String",function(t){this._t=String(t),this._i=0},function(){var t,n=this._t,r=this._i;return r>=n.length?{value:void 0,done:!0}:(t=e(n,r),this._i+=t.length,{value:t,done:!1})})},function(t,n,r){"use strict";r(29)("link",function(t){return function(n){return t(this,"a","href",n)}})},function(t,n,r){var e=r(1),i=r(30),o=r(16);e(e.S,"String",{raw:function(t){for(var n=i(t.raw),r=o(n.length),e=arguments.length,u=[],c=0;r>c;)u.push(String(n[c++])),c<e&&u.push(String(arguments[c]));return u.join("")}})},function(t,n,r){var e=r(1);e(e.P,"String",{repeat:r(149)})},function(t,n,r){"use strict";r(29)("small",function(t){return function(){return t(this,"small","","")}})},function(t,n,r){"use strict";var e=r(1),i=r(16),o=r(148),u="startsWith",c=""[u];e(e.P+e.F*r(134)(u),"String",{startsWith:function(t){var n=o(this,t,u),r=i(Math.min(arguments.length>1?arguments[1]:void 0,n.length)),e=String(t);return c?c.call(n,e,r):n.slice(r,r+e.length)===e}})},function(t,n,r){"use strict";r(29)("strike",function(t){return function(){return t(this,"strike","","")}})},function(t,n,r){"use strict";r(29)("sub",function(t){return function(){return t(this,"sub","","")}})},function(t,n,r){"use strict";r(29)("sup",function(t){return function(){return t(this,"sup","","")}})},function(t,n,r){"use strict";r(82)("trim",function(t){return function(){return t(this,3)}})},function(t,n,r){"use strict";var e=r(3),i=r(24),o=r(10),u=r(1),c=r(28),f=r(65).KEY,a=r(4),s=r(126),l=r(81),h=r(76),v=r(7),p=r(182),d=r(153),y=r(206),g=r(205),b=r(138),m=r(2),x=r(30),w=r(50),S=r(66),_=r(70),O=r(174),E=r(31),P=r(11),j=r(72),F=E.f,M=P.f,A=O.f,N=e.Symbol,T=e.JSON,I=T&&T.stringify,k="prototype",L=v("_hidden"),R=v("toPrimitive"),C={}.propertyIsEnumerable,D=s("symbol-registry"),U=s("symbols"),W=s("op-symbols"),G=Object[k],B="function"==typeof N,V=e.QObject,z=!V||!V[k]||!V[k].findChild,q=o&&a(function(){return 7!=_(M({},"a",{get:function(){return M(this,"a",{value:7}).a}})).a})?function(t,n,r){var e=F(G,n);e&&delete G[n],M(t,n,r),e&&t!==G&&M(G,n,e)}:M,K=function(t){var n=U[t]=_(N[k]);return n._k=t,n},J=B&&"symbol"==typeof N.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof N},Y=function(t,n,r){return t===G&&Y(W,n,r),m(t),n=w(n,!0),m(r),i(U,n)?(r.enumerable?(i(t,L)&&t[L][n]&&(t[L][n]=!1),r=_(r,{enumerable:S(0,!1)})):(i(t,L)||M(t,L,S(1,{})),t[L][n]=!0),q(t,n,r)):M(t,n,r)},H=function(t,n){m(t);for(var r,e=g(n=x(n)),i=0,o=e.length;o>i;)Y(t,r=e[i++],n[r]);return t},$=function(t,n){return void 0===n?_(t):H(_(t),n)},X=function(t){var n=C.call(this,t=w(t,!0));return!(this===G&&i(U,t)&&!i(W,t))&&(!(n||!i(this,t)||!i(U,t)||i(this,L)&&this[L][t])||n)},Q=function(t,n){if(t=x(t),n=w(n,!0),t!==G||!i(U,n)||i(W,n)){var r=F(t,n);return!r||!i(U,n)||i(t,L)&&t[L][n]||(r.enumerable=!0),r}},Z=function(t){for(var n,r=A(x(t)),e=[],o=0;r.length>o;)i(U,n=r[o++])||n==L||n==f||e.push(n);return e},tt=function(t){for(var n,r=t===G,e=A(r?W:x(t)),o=[],u=0;e.length>u;)!i(U,n=e[u++])||r&&!i(G,n)||o.push(U[n]);return o};B||(N=function(){if(this instanceof N)throw TypeError("Symbol is not a constructor!");var t=h(arguments.length>0?arguments[0]:void 0),n=function(r){this===G&&n.call(W,r),i(this,L)&&i(this[L],t)&&(this[L][t]=!1),q(this,t,S(1,r))};return o&&z&&q(G,t,{configurable:!0,set:n}),K(t)},c(N[k],"toString",function(){return this._k}),E.f=Q,P.f=Y,r(71).f=O.f=Z,r(116).f=X,r(125).f=tt,o&&!r(69)&&c(G,"propertyIsEnumerable",X,!0),p.f=function(t){return K(v(t))}),u(u.G+u.W+u.F*!B,{Symbol:N});for(var nt="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),rt=0;nt.length>rt;)v(nt[rt++]);for(var nt=j(v.store),rt=0;nt.length>rt;)d(nt[rt++]);u(u.S+u.F*!B,"Symbol",{for:function(t){return i(D,t+="")?D[t]:D[t]=N(t)},keyFor:function(t){if(J(t))return y(D,t);throw TypeError(t+" is not a symbol!")},useSetter:function(){z=!0},useSimple:function(){z=!1}}),u(u.S+u.F*!B,"Object",{create:$,defineProperty:Y,defineProperties:H,getOwnPropertyDescriptor:Q,getOwnPropertyNames:Z,getOwnPropertySymbols:tt}),T&&u(u.S+u.F*(!B||a(function(){var t=N();return"[null]"!=I([t])||"{}"!=I({a:t})||"{}"!=I(Object(t))})),"JSON",{stringify:function(t){if(void 0!==t&&!J(t)){for(var n,r,e=[t],i=1;arguments.length>i;)e.push(arguments[i++]);return n=e[1],"function"==typeof n&&(r=n),!r&&b(n)||(n=function(t,n){if(r&&(n=r.call(this,t,n)),!J(n))return n}),e[1]=n,I.apply(T,e)}}}),N[k][R]||r(27)(N[k],R,N[k].valueOf),l(N,"Symbol"),l(Math,"Math",!0),l(e.JSON,"JSON",!0)},function(t,n,r){"use strict";var e=r(1),i=r(127),o=r(152),u=r(2),c=r(75),f=r(16),a=r(6),s=r(3).ArrayBuffer,l=r(146),h=o.ArrayBuffer,v=o.DataView,p=i.ABV&&s.isView,d=h.prototype.slice,y=i.VIEW,g="ArrayBuffer";e(e.G+e.W+e.F*(s!==h),{ArrayBuffer:h}),e(e.S+e.F*!i.CONSTR,g,{isView:function(t){return p&&p(t)||a(t)&&y in t}}),e(e.P+e.U+e.F*r(4)(function(){return!new h(2).slice(1,void 0).byteLength}),g,{slice:function(t,n){if(void 0!==d&&void 0===n)return d.call(u(this),t);for(var r=u(this).byteLength,e=c(t,r),i=c(void 0===n?r:n,r),o=new(l(this,h))(f(i-e)),a=new v(this),s=new v(o),p=0;e<i;)s.setUint8(p++,a.getUint8(e++));return o}}),r(74)(g)},function(t,n,r){var e=r(1);e(e.G+e.W+e.F*!r(127).ABV,{DataView:r(152).DataView})},function(t,n,r){r(55)("Float32",4,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){r(55)("Float64",8,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){r(55)("Int16",2,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){r(55)("Int32",4,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){r(55)("Int8",1,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){r(55)("Uint16",2,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){r(55)("Uint32",4,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){r(55)("Uint8",1,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){r(55)("Uint8",1,function(t){return function(n,r,e){return t(this,n,r,e)}},!0)},function(t,n,r){"use strict";var e=r(166);r(118)("WeakSet",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{add:function(t){return e.def(this,t,!0)}},e,!1,!0)},function(t,n,r){"use strict";var e=r(1),i=r(117)(!0);e(e.P,"Array",{includes:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),r(78)("includes")},function(t,n,r){var e=r(1),i=r(143)(),o=r(3).process,u="process"==r(45)(o);e(e.G,{asap:function(t){var n=u&&o.domain;i(n?n.bind(t):t)}})},function(t,n,r){var e=r(1),i=r(45);e(e.S,"Error",{isError:function(t){return"Error"===i(t)}})},function(t,n,r){var e=r(1);e(e.P+e.R,"Map",{toJSON:r(165)("Map")})},function(t,n,r){var e=r(1);e(e.S,"Math",{iaddh:function(t,n,r,e){var i=t>>>0,o=n>>>0,u=r>>>0;return o+(e>>>0)+((i&u|(i|u)&~(i+u>>>0))>>>31)|0}})},function(t,n,r){var e=r(1);e(e.S,"Math",{imulh:function(t,n){var r=65535,e=+t,i=+n,o=e&r,u=i&r,c=e>>16,f=i>>16,a=(c*u>>>0)+(o*u>>>16);return c*f+(a>>16)+((o*f>>>0)+(a&r)>>16)}})},function(t,n,r){var e=r(1);e(e.S,"Math",{isubh:function(t,n,r,e){var i=t>>>0,o=n>>>0,u=r>>>0;return o-(e>>>0)-((~i&u|~(i^u)&i-u>>>0)>>>31)|0}})},function(t,n,r){var e=r(1);e(e.S,"Math",{umulh:function(t,n){var r=65535,e=+t,i=+n,o=e&r,u=i&r,c=e>>>16,f=i>>>16,a=(c*u>>>0)+(o*u>>>16);return c*f+(a>>>16)+((o*f>>>0)+(a&r)>>>16)}})},function(t,n,r){"use strict";var e=r(1),i=r(17),o=r(26),u=r(11);r(10)&&e(e.P+r(124),"Object",{__defineGetter__:function(t,n){u.f(i(this),t,{get:o(n),enumerable:!0,configurable:!0})}})},function(t,n,r){"use strict";var e=r(1),i=r(17),o=r(26),u=r(11);r(10)&&e(e.P+r(124),"Object",{__defineSetter__:function(t,n){u.f(i(this),t,{set:o(n),enumerable:!0,configurable:!0})}})},function(t,n,r){var e=r(1),i=r(176)(!0);e(e.S,"Object",{entries:function(t){return i(t)}})},function(t,n,r){var e=r(1),i=r(177),o=r(30),u=r(31),c=r(131);e(e.S,"Object",{getOwnPropertyDescriptors:function(t){for(var n,r=o(t),e=u.f,f=i(r),a={},s=0;f.length>s;)c(a,n=f[s++],e(r,n));return a}})},function(t,n,r){"use strict";var e=r(1),i=r(17),o=r(50),u=r(32),c=r(31).f;r(10)&&e(e.P+r(124),"Object",{__lookupGetter__:function(t){var n,r=i(this),e=o(t,!0);do{if(n=c(r,e))return n.get}while(r=u(r))}})},function(t,n,r){"use strict";var e=r(1),i=r(17),o=r(50),u=r(32),c=r(31).f;r(10)&&e(e.P+r(124),"Object",{__lookupSetter__:function(t){var n,r=i(this),e=o(t,!0);do{if(n=c(r,e))return n.set}while(r=u(r))}})},function(t,n,r){var e=r(1),i=r(176)(!1);e(e.S,"Object",{values:function(t){return i(t)}})},function(t,n,r){"use strict";var e=r(1),i=r(3),o=r(52),u=r(143)(),c=r(7)("observable"),f=r(26),a=r(2),s=r(68),l=r(73),h=r(27),v=r(79),p=v.RETURN,d=function(t){return null==t?void 0:f(t)},y=function(t){var n=t._c;n&&(t._c=void 0,n())},g=function(t){return void 0===t._o},b=function(t){g(t)||(t._o=void 0,y(t))},m=function(t,n){a(t),this._c=void 0,this._o=t,t=new x(this);try{var r=n(t),e=r;null!=r&&("function"==typeof r.unsubscribe?r=function(){e.unsubscribe()}:f(r),this._c=r)}catch(n){return void t.error(n)}g(this)&&y(this)};m.prototype=l({},{unsubscribe:function(){b(this)}});var x=function(t){this._s=t};x.prototype=l({},{next:function(t){var n=this._s;if(!g(n)){var r=n._o;try{var e=d(r.next);if(e)return e.call(r,t)}catch(t){try{b(n)}finally{throw t}}}},error:function(t){var n=this._s;if(g(n))throw t;var r=n._o;n._o=void 0;try{var e=d(r.error);if(!e)throw t;t=e.call(r,t)}catch(t){try{y(n)}finally{throw t}}return y(n),t},complete:function(t){var n=this._s;if(!g(n)){var r=n._o;n._o=void 0;try{var e=d(r.complete);t=e?e.call(r,t):void 0}catch(t){try{y(n)}finally{throw t}}return y(n),t}}});var w=function(t){s(this,w,"Observable","_f")._f=f(t)};l(w.prototype,{subscribe:function(t){return new m(t,this._f)},forEach:function(t){var n=this;return new(o.Promise||i.Promise)(function(r,e){f(t);var i=n.subscribe({next:function(n){try{return t(n)}catch(t){e(t),i.unsubscribe()}},error:e,complete:r})})}}),l(w,{from:function(t){var n="function"==typeof this?this:w,r=d(a(t)[c]);if(r){var e=a(r.call(t));return e.constructor===n?e:new n(function(t){return e.subscribe(t)})}return new n(function(n){var r=!1;return u(function(){if(!r){try{if(v(t,!1,function(t){if(n.next(t),r)return p})===p)return}catch(t){if(r)throw t;return void n.error(t)}n.complete()}}),function(){r=!0}})},of:function(){for(var t=0,n=arguments.length,r=Array(n);t<n;)r[t]=arguments[t++];return new("function"==typeof this?this:w)(function(t){var n=!1;return u(function(){if(!n){for(var e=0;e<r.length;++e)if(t.next(r[e]),n)return;t.complete()}}),function(){n=!0}})}}),h(w.prototype,c,function(){return this}),e(e.G,{Observable:w}),r(74)("Observable")},function(t,n,r){var e=r(54),i=r(2),o=e.key,u=e.set;e.exp({defineMetadata:function(t,n,r,e){u(t,n,i(r),o(e))}})},function(t,n,r){var e=r(54),i=r(2),o=e.key,u=e.map,c=e.store;e.exp({deleteMetadata:function(t,n){var r=arguments.length<3?void 0:o(arguments[2]),e=u(i(n),r,!1);if(void 0===e||!e.delete(t))return!1;if(e.size)return!0;var f=c.get(n);return f.delete(r),!!f.size||c.delete(n)}})},function(t,n,r){var e=r(185),i=r(161),o=r(54),u=r(2),c=r(32),f=o.keys,a=o.key,s=function(t,n){var r=f(t,n),o=c(t);if(null===o)return r;var u=s(o,n);return u.length?r.length?i(new e(r.concat(u))):u:r};o.exp({getMetadataKeys:function(t){return s(u(t),arguments.length<2?void 0:a(arguments[1]))}})},function(t,n,r){var e=r(54),i=r(2),o=r(32),u=e.has,c=e.get,f=e.key,a=function(t,n,r){if(u(t,n,r))return c(t,n,r);var e=o(n);return null!==e?a(t,e,r):void 0};e.exp({getMetadata:function(t,n){return a(t,i(n),arguments.length<3?void 0:f(arguments[2]))}})},function(t,n,r){var e=r(54),i=r(2),o=e.keys,u=e.key;e.exp({getOwnMetadataKeys:function(t){
return o(i(t),arguments.length<2?void 0:u(arguments[1]))}})},function(t,n,r){var e=r(54),i=r(2),o=e.get,u=e.key;e.exp({getOwnMetadata:function(t,n){return o(t,i(n),arguments.length<3?void 0:u(arguments[2]))}})},function(t,n,r){var e=r(54),i=r(2),o=r(32),u=e.has,c=e.key,f=function(t,n,r){if(u(t,n,r))return!0;var e=o(n);return null!==e&&f(t,e,r)};e.exp({hasMetadata:function(t,n){return f(t,i(n),arguments.length<3?void 0:c(arguments[2]))}})},function(t,n,r){var e=r(54),i=r(2),o=e.has,u=e.key;e.exp({hasOwnMetadata:function(t,n){return o(t,i(n),arguments.length<3?void 0:u(arguments[2]))}})},function(t,n,r){var e=r(54),i=r(2),o=r(26),u=e.key,c=e.set;e.exp({metadata:function(t,n){return function(r,e){c(t,n,(void 0!==e?i:o)(r),u(e))}}})},function(t,n,r){var e=r(1);e(e.P+e.R,"Set",{toJSON:r(165)("Set")})},function(t,n,r){"use strict";var e=r(1),i=r(147)(!0);e(e.P,"String",{at:function(t){return i(this,t)}})},function(t,n,r){"use strict";var e=r(1),i=r(46),o=r(16),u=r(122),c=r(120),f=RegExp.prototype,a=function(t,n){this._r=t,this._s=n};r(139)(a,"RegExp String",function(){var t=this._r.exec(this._s);return{value:t,done:null===t}}),e(e.P,"String",{matchAll:function(t){if(i(this),!u(t))throw TypeError(t+" is not a regexp!");var n=String(this),r="flags"in f?String(t.flags):c.call(t),e=new RegExp(t.source,~r.indexOf("g")?r:"g"+r);return e.lastIndex=o(t.lastIndex),new a(e,n)}})},function(t,n,r){"use strict";var e=r(1),i=r(181);e(e.P,"String",{padEnd:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0,!1)}})},function(t,n,r){"use strict";var e=r(1),i=r(181);e(e.P,"String",{padStart:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0,!0)}})},function(t,n,r){"use strict";r(82)("trimLeft",function(t){return function(){return t(this,1)}},"trimStart")},function(t,n,r){"use strict";r(82)("trimRight",function(t){return function(){return t(this,2)}},"trimEnd")},function(t,n,r){r(153)("asyncIterator")},function(t,n,r){r(153)("observable")},function(t,n,r){var e=r(1);e(e.S,"System",{global:r(3)})},function(t,n,r){for(var e=r(155),i=r(28),o=r(3),u=r(27),c=r(80),f=r(7),a=f("iterator"),s=f("toStringTag"),l=c.Array,h=["NodeList","DOMTokenList","MediaList","StyleSheetList","CSSRuleList"],v=0;v<5;v++){var p,d=h[v],y=o[d],g=y&&y.prototype;if(g){g[a]||u(g,a,l),g[s]||u(g,s,d),c[d]=l;for(p in e)g[p]||i(g,p,e[p],!0)}}},function(t,n,r){var e=r(1),i=r(151);e(e.G+e.B,{setImmediate:i.set,clearImmediate:i.clear})},function(t,n,r){var e=r(3),i=r(1),o=r(121),u=r(207),c=e.navigator,f=!!c&&/MSIE .\./.test(c.userAgent),a=function(t){return f?function(n,r){return t(o(u,[].slice.call(arguments,2),"function"==typeof n?n:Function(n)),r)}:t};i(i.G+i.B+i.F*f,{setTimeout:a(e.setTimeout),setInterval:a(e.setInterval)})},function(t,n,r){r(330),r(269),r(271),r(270),r(273),r(275),r(280),r(274),r(272),r(282),r(281),r(277),r(278),r(276),r(268),r(279),r(283),r(284),r(236),r(238),r(237),r(286),r(285),r(256),r(266),r(267),r(257),r(258),r(259),r(260),r(261),r(262),r(263),r(264),r(265),r(239),r(240),r(241),r(242),r(243),r(244),r(245),r(246),r(247),r(248),r(249),r(250),r(251),r(252),r(253),r(254),r(255),r(317),r(322),r(329),r(320),r(312),r(313),r(318),r(323),r(325),r(308),r(309),r(310),r(311),r(314),r(315),r(316),r(319),r(321),r(324),r(326),r(327),r(328),r(231),r(233),r(232),r(235),r(234),r(220),r(218),r(224),r(221),r(227),r(229),r(217),r(223),r(214),r(228),r(212),r(226),r(225),r(219),r(222),r(211),r(213),r(216),r(215),r(230),r(155),r(302),r(307),r(184),r(303),r(304),r(305),r(306),r(287),r(183),r(185),r(186),r(342),r(331),r(332),r(337),r(340),r(341),r(335),r(338),r(336),r(339),r(333),r(334),r(288),r(289),r(290),r(291),r(292),r(295),r(293),r(294),r(296),r(297),r(298),r(299),r(301),r(300),r(343),r(369),r(372),r(371),r(373),r(374),r(370),r(375),r(376),r(354),r(357),r(353),r(351),r(352),r(355),r(356),r(346),r(368),r(377),r(345),r(347),r(349),r(348),r(350),r(359),r(360),r(362),r(361),r(364),r(363),r(365),r(366),r(367),r(344),r(358),r(380),r(379),r(378),t.exports=r(52)},function(t,n){function r(t,n){if("string"==typeof n)return t.insertAdjacentHTML("afterend",n);var r=t.nextSibling;return r?t.parentNode.insertBefore(n,r):t.parentNode.appendChild(n)}t.exports=r},,,,,,,,,function(t,n,r){(function(n,r){!function(n){"use strict";function e(t,n,r,e){var i=n&&n.prototype instanceof o?n:o,u=Object.create(i.prototype),c=new p(e||[]);return u._invoke=s(t,r,c),u}function i(t,n,r){try{return{type:"normal",arg:t.call(n,r)}}catch(t){return{type:"throw",arg:t}}}function o(){}function u(){}function c(){}function f(t){["next","throw","return"].forEach(function(n){t[n]=function(t){return this._invoke(n,t)}})}function a(t){function n(r,e,o,u){var c=i(t[r],t,e);if("throw"!==c.type){var f=c.arg,a=f.value;return a&&"object"==typeof a&&m.call(a,"__await")?Promise.resolve(a.__await).then(function(t){n("next",t,o,u)},function(t){n("throw",t,o,u)}):Promise.resolve(a).then(function(t){f.value=t,o(f)},u)}u(c.arg)}function e(t,r){function e(){return new Promise(function(e,i){n(t,r,e,i)})}return o=o?o.then(e,e):e()}"object"==typeof r&&r.domain&&(n=r.domain.bind(n));var o;this._invoke=e}function s(t,n,r){var e=P;return function(o,u){if(e===F)throw new Error("Generator is already running");if(e===M){if("throw"===o)throw u;return y()}for(r.method=o,r.arg=u;;){var c=r.delegate;if(c){var f=l(c,r);if(f){if(f===A)continue;return f}}if("next"===r.method)r.sent=r._sent=r.arg;else if("throw"===r.method){if(e===P)throw e=M,r.arg;r.dispatchException(r.arg)}else"return"===r.method&&r.abrupt("return",r.arg);e=F;var a=i(t,n,r);if("normal"===a.type){if(e=r.done?M:j,a.arg===A)continue;return{value:a.arg,done:r.done}}"throw"===a.type&&(e=M,r.method="throw",r.arg=a.arg)}}}function l(t,n){var r=t.iterator[n.method];if(r===g){if(n.delegate=null,"throw"===n.method){if(t.iterator.return&&(n.method="return",n.arg=g,l(t,n),"throw"===n.method))return A;n.method="throw",n.arg=new TypeError("The iterator does not provide a 'throw' method")}return A}var e=i(r,t.iterator,n.arg);if("throw"===e.type)return n.method="throw",n.arg=e.arg,n.delegate=null,A;var o=e.arg;return o?o.done?(n[t.resultName]=o.value,n.next=t.nextLoc,"return"!==n.method&&(n.method="next",n.arg=g),n.delegate=null,A):o:(n.method="throw",n.arg=new TypeError("iterator result is not an object"),n.delegate=null,A)}function h(t){var n={tryLoc:t[0]};1 in t&&(n.catchLoc=t[1]),2 in t&&(n.finallyLoc=t[2],n.afterLoc=t[3]),this.tryEntries.push(n)}function v(t){var n=t.completion||{};n.type="normal",delete n.arg,t.completion=n}function p(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(h,this),this.reset(!0)}function d(t){if(t){var n=t[w];if(n)return n.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var r=-1,e=function n(){for(;++r<t.length;)if(m.call(t,r))return n.value=t[r],n.done=!1,n;return n.value=g,n.done=!0,n};return e.next=e}}return{next:y}}function y(){return{value:g,done:!0}}var g,b=Object.prototype,m=b.hasOwnProperty,x="function"==typeof Symbol?Symbol:{},w=x.iterator||"@@iterator",S=x.asyncIterator||"@@asyncIterator",_=x.toStringTag||"@@toStringTag",O="object"==typeof t,E=n.regeneratorRuntime;if(E)return void(O&&(t.exports=E));E=n.regeneratorRuntime=O?t.exports:{},E.wrap=e;var P="suspendedStart",j="suspendedYield",F="executing",M="completed",A={},N={};N[w]=function(){return this};var T=Object.getPrototypeOf,I=T&&T(T(d([])));I&&I!==b&&m.call(I,w)&&(N=I);var k=c.prototype=o.prototype=Object.create(N);u.prototype=k.constructor=c,c.constructor=u,c[_]=u.displayName="GeneratorFunction",E.isGeneratorFunction=function(t){var n="function"==typeof t&&t.constructor;return!!n&&(n===u||"GeneratorFunction"===(n.displayName||n.name))},E.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,c):(t.__proto__=c,_ in t||(t[_]="GeneratorFunction")),t.prototype=Object.create(k),t},E.awrap=function(t){return{__await:t}},f(a.prototype),a.prototype[S]=function(){return this},E.AsyncIterator=a,E.async=function(t,n,r,i){var o=new a(e(t,n,r,i));return E.isGeneratorFunction(n)?o:o.next().then(function(t){return t.done?t.value:o.next()})},f(k),k[_]="Generator",k.toString=function(){return"[object Generator]"},E.keys=function(t){var n=[];for(var r in t)n.push(r);return n.reverse(),function r(){for(;n.length;){var e=n.pop();if(e in t)return r.value=e,r.done=!1,r}return r.done=!0,r}},E.values=d,p.prototype={constructor:p,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=g,this.done=!1,this.delegate=null,this.method="next",this.arg=g,this.tryEntries.forEach(v),!t)for(var n in this)"t"===n.charAt(0)&&m.call(this,n)&&!isNaN(+n.slice(1))&&(this[n]=g)},stop:function(){this.done=!0;var t=this.tryEntries[0],n=t.completion;if("throw"===n.type)throw n.arg;return this.rval},dispatchException:function(t){function n(n,e){return o.type="throw",o.arg=t,r.next=n,e&&(r.method="next",r.arg=g),!!e}if(this.done)throw t;for(var r=this,e=this.tryEntries.length-1;e>=0;--e){var i=this.tryEntries[e],o=i.completion;if("root"===i.tryLoc)return n("end");if(i.tryLoc<=this.prev){var u=m.call(i,"catchLoc"),c=m.call(i,"finallyLoc");if(u&&c){if(this.prev<i.catchLoc)return n(i.catchLoc,!0);if(this.prev<i.finallyLoc)return n(i.finallyLoc)}else if(u){if(this.prev<i.catchLoc)return n(i.catchLoc,!0)}else{if(!c)throw new Error("try statement without catch or finally");if(this.prev<i.finallyLoc)return n(i.finallyLoc)}}}},abrupt:function(t,n){for(var r=this.tryEntries.length-1;r>=0;--r){var e=this.tryEntries[r];if(e.tryLoc<=this.prev&&m.call(e,"finallyLoc")&&this.prev<e.finallyLoc){var i=e;break}}i&&("break"===t||"continue"===t)&&i.tryLoc<=n&&n<=i.finallyLoc&&(i=null);var o=i?i.completion:{};return o.type=t,o.arg=n,i?(this.method="next",this.next=i.finallyLoc,A):this.complete(o)},complete:function(t,n){if("throw"===t.type)throw t.arg;return"break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&n&&(this.next=n),A},finish:function(t){for(var n=this.tryEntries.length-1;n>=0;--n){var r=this.tryEntries[n];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),v(r),A}},catch:function(t){for(var n=this.tryEntries.length-1;n>=0;--n){var r=this.tryEntries[n];if(r.tryLoc===t){var e=r.completion;if("throw"===e.type){var i=e.arg;v(r)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(t,n,r){return this.delegate={iterator:d(t),resultName:n,nextLoc:r},"next"===this.method&&(this.arg=g),A}}}("object"==typeof n?n:"object"==typeof window?window:"object"==typeof self?self:this)}).call(n,function(){return this}(),r(158))}])</script><script src="/blog/./main.0cf68a.js"></script><script>!function(){!function(e){var t=document.createElement("script");document.getElementsByTagName("body")[0].appendChild(t),t.setAttribute("src",e)}("/blog/slider.e37972.js")}()</script>


    
<div class="tools-col" q-class="show:isShow,hide:isShow|isFalse" q-on="click:stop(e)">
  <div class="tools-nav header-menu">
    
    
      
      
      
    
      
      
      
    
      
      
      
    
    

    <ul style="width: 70%">
    
    
      
      <li style="width: 33.333333333333336%" q-on="click: openSlider(e, 'innerArchive')"><a href="javascript:void(0)" q-class="active:innerArchive">所有文章</a></li>
      
        
      
      <li style="width: 33.333333333333336%" q-on="click: openSlider(e, 'friends')"><a href="javascript:void(0)" q-class="active:friends">友链</a></li>
      
        
      
      <li style="width: 33.333333333333336%" q-on="click: openSlider(e, 'aboutme')"><a href="javascript:void(0)" q-class="active:aboutme">关于我</a></li>
      
        
    </ul>
  </div>
  <div class="tools-wrap">
    
    	<section class="tools-section tools-section-all" q-show="innerArchive">
        <div class="search-wrap">
          <input class="search-ipt" q-model="search" type="text" placeholder="find something…">
          <i class="icon-search icon" q-show="search|isEmptyStr"></i>
          <i class="icon-close icon" q-show="search|isNotEmptyStr" q-on="click:clearChose(e)"></i>
        </div>
        <div class="widget tagcloud search-tag">
          <p class="search-tag-wording">tag:</p>
          <label class="search-switch">
            <input type="checkbox" q-on="click:toggleTag(e)" q-attr="checked:showTags">
          </label>
          <ul class="article-tag-list" q-show="showTags">
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color3">Node.js</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color3">面试</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color3">工具</a>
              </li>
             
              <li class="article-tag-list-item">
                <a href="javascript:void(0)" class="js-tag color5">Vue2</a>
              </li>
            
            <div class="clearfix"></div>
          </ul>
        </div>
        <ul class="search-ul">
          <p q-show="jsonFail" style="padding: 20px; font-size: 12px;">
            缺失模块。<br/>1、请确保node版本大于6.2<br/>2、在博客根目录（注意不是yilia根目录）执行以下命令：<br/> npm i hexo-generator-json-content --save<br/><br/>
            3、在根目录_config.yml里添加配置：
<pre style="font-size: 12px;" q-show="jsonFail">
  jsonContent:
    meta: false
    pages: false
    posts:
      title: true
      date: true
      path: true
      text: false
      raw: false
      content: false
      slug: false
      updated: false
      comments: false
      link: false
      permalink: false
      excerpt: false
      categories: false
      tags: true
</pre>
          </p>
          <li class="search-li" q-repeat="items" q-show="isShow">
            <a q-attr="href:path|urlformat" class="search-title"><i class="icon-quo-left icon"></i><span q-text="title"></span></a>
            <p class="search-time">
              <i class="icon-calendar icon"></i>
              <span q-text="date|dateformat"></span>
            </p>
            <p class="search-tag">
              <i class="icon-price-tags icon"></i>
              <span q-repeat="tags" q-on="click:choseTag(e, name)" q-text="name|tagformat"></span>
            </p>
          </li>
        </ul>
    	</section>
    

    
    	<section class="tools-section tools-section-friends" q-show="friends">
  		
        <ul class="search-ul">
          
            <li class="search-li">
              <a href="http://localhost:4000/" target="_blank" class="search-title"><i class="icon-quo-left icon"></i>友情链接1</a>
            </li>
          
            <li class="search-li">
              <a href="http://localhost:4000/" target="_blank" class="search-title"><i class="icon-quo-left icon"></i>友情链接2</a>
            </li>
          
            <li class="search-li">
              <a href="http://localhost:4000/" target="_blank" class="search-title"><i class="icon-quo-left icon"></i>友情链接3</a>
            </li>
          
            <li class="search-li">
              <a href="http://localhost:4000/" target="_blank" class="search-title"><i class="icon-quo-left icon"></i>友情链接4</a>
            </li>
          
            <li class="search-li">
              <a href="http://localhost:4000/" target="_blank" class="search-title"><i class="icon-quo-left icon"></i>友情链接5</a>
            </li>
          
            <li class="search-li">
              <a href="http://localhost:4000/" target="_blank" class="search-title"><i class="icon-quo-left icon"></i>友情链接6</a>
            </li>
          
        </ul>
  		
    	</section>
    

    
    	<section class="tools-section tools-section-me" q-show="aboutme">
  	  	
  	  		<div class="aboutme-wrap" id="js-aboutme">你要明白,世上最牢靠的肩膀与双手,长在你自己身上,越努力越幸运!</div>
  	  	
    	</section>
    
  </div>
  
</div>
    <!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

    <!-- Background of PhotoSwipe. 
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>

    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">

        <!-- Container that holds slides. 
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>

        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">

            <div class="pswp__top-bar">

                <!--  Controls are self-explanatory. Order can be changed. -->

                <div class="pswp__counter"></div>

                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

                <button class="pswp__button pswp__button--share" style="display:none" title="Share"></button>

                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                      <div class="pswp__preloader__cut">
                        <div class="pswp__preloader__donut"></div>
                      </div>
                    </div>
                </div>
            </div>

            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div> 
            </div>

            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>

            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>

            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>

        </div>

    </div>

</div>
  </div>
</body>
</html>